const std = @import("std");
const omt = @cImport(@cInclude("libomt.h"));

fn discoverStream() ?[*c]u8 {
    var discovery_count: i32 = 0;

    while (discovery_count == 0) {
        const discovered = omt.omt_discovery_getaddresses(&discovery_count);
        std.log.info("Found {} streams:", .{discovery_count});

        const count: usize = @intCast(discovery_count);
        for (0..count) |i| {
            const name = discovered[i];
            std.log.info("  {s}", .{name});
        }

        if (discovery_count > 0) {
            return discovered[0];
        }
        std.Thread.sleep(1000 * 1000 * 1000);
    }
    return null;
}

pub fn main() !void {
    // var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    // const allocator = gpa.allocator();

    std.log.info("Receiving...", .{});
    omt.omt_setloggingfilename("omtrecvtest.log");

    const stream = discoverStream() orelse undefined;

    // TODO: How to coerce C string array into something printable again?
    // std.log.info("Listening to {s}", @as([*:0]u8, stream));

    const frametype_flags = omt.OMTFrameType_Video | omt.OMTFrameType_Audio | omt.OMTFrameType_Metadata;
    const receiver = omt.omt_receive_create(
        stream,
        frametype_flags,
        omt.OMTPreferredVideoFormat_UYVYorBGRA,
        0,
    );
    defer omt.omt_receive_destroy(receiver);

    while (true) {
        const frame = omt.omt_receive(receiver, frametype_flags, 40);
        if (frame != null) {
            dumpOMTMediaFrameInfo(frame);
        }
    }
}

fn dumpOMTMediaFrameInfo(frame: *omt.OMTMediaFrame) void {
    std.log.info("--------- Received --------", .{});
    switch (frame.*.Type) {
        omt.OMTFrameType_Video => dumpVideoFrameInfo(frame),
        omt.OMTFrameType_Audio => dumpAudioFrameInfo(frame),
        omt.OMTFrameType_Metadata => dumpMetadataFrameInfo(frame),
        else => std.log.err("Undefined frame type", .{}),
    }
}

fn dumpVideoFrameInfo(frame: *omt.OMTMediaFrame) void {
    std.log.info("Frame: Video", .{});
    _ = frame;
}

fn dumpAudioFrameInfo(frame: *omt.OMTMediaFrame) void {
    std.log.info("Frame: Audio", .{});
    _ = frame;
}

fn dumpMetadataFrameInfo(frame: *omt.OMTMediaFrame) void {
    std.log.info("Frame: Metadata", .{});
    _ = frame;
}
