const std = @import("std");
const Thread = std.Thread;
const info = std.log.info;
const Queue = std.atomic.Queue;

const Task = struct {
    row_idx: usize,
    row_pixels: []u8,
};

fn worker(q: *Queue(Task)) void {
    while (true) {
        if (q.get()) |node| {
            const task = node.data;
            info("starting thread: {}", .{task.row_idx});
        } else {
            return;
        }
    }
}

pub fn main() anyerror!void {
    const allocator = std.heap.page_allocator;
    const cpus = try Thread.getCpuCount();
    const width = 512;
    const height = 256;
    var pixels: [width * height * 3]u8 = undefined;

    var threads: std.ArrayList(std.Thread) = std.ArrayList(std.Thread).init(allocator);
    var q = Queue(Task).init();
    const Node = Queue(Task).Node;
    var row: usize = 0;
    while (row < height) : (row += 1) {
        const node = try allocator.create(Node);
        node.* = .{
            .prev = undefined,
            .next = undefined,
            .data = Task{
                .row_idx = row,
                .row_pixels = pixels[row * width * 3 .. (row + 1) * width * 3],
            },
        };
        q.put(node);
    }

    var t: usize = 0;
    while (t < cpus) : (t += 1) {
        try threads.append(try Thread.spawn(.{}, worker, .{&q}));
    }

    // Wait for all threads to finish.
    for (threads.items) |thread| {
        Thread.join(thread);
    }
    info("main done", .{});
}
