const std = @import("std");

const Blocks = .{
    @import("Cpu.zig").block(.{}),
    @import("Cpu.zig").block(.{}),  // just testing a second block
};

const freq_ms = 500;

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const alloc = gpa.allocator();

    var blocks: std.meta.Tuple(&Blocks) = undefined;
    var arenas: [Blocks.len]std.heap.ArenaAllocator = undefined;
    var outputs: [Blocks.len][]const u8 = undefined;

    var combined_arena = std.heap.ArenaAllocator.init(alloc);
    defer combined_arena.deinit();

    inline for (Blocks, &blocks, &arenas) |Block, *block, *arena| {
        block.* = try Block.init(alloc);
        arena.* = std.heap.ArenaAllocator.init(alloc);
    }

    defer inline for (blocks, arenas) |block, arena| {
        block.deinit(alloc);
        arena.deinit();
    };

    std.time.sleep(std.time.ns_per_s);

    inline for (&blocks, &arenas, &outputs) |*block, *arena, *output| {
        output.* = try block.update(arena.allocator());
    }

    _ = combined_arena.reset(.retain_capacity);
    const combined = try std.mem.join(combined_arena.allocator(), " * ", &outputs);
    try std.io.getStdOut().writeAll(combined);
    try std.io.getStdOut().writeAll("\n");
}

// pub fn main() !void {
//     var arenas: [Blocks.len]std.heap.ArenaAllocator = undefined;
//     inline for (&arenas) |*arena| {
//         arena.* = std.heap.ArenaAllocator.init(alloc);
//     }
//
//     var outs: [Blocks.len][]u8 = undefined;
//
//     var buf = std.ArrayList(u8).init(alloc);
//     defer buf.deinit();
//     try buf.ensureTotalCapacity(512);
//
//     while (true) {
//         inline for (&blocks, &arenas, &outs) |*block, *arena, *out| {
//             arena.reset(.{ .retain_with_limit = 100 });
//             out.* = try block.update(arena.allocator());
//         }
//
//         std.mem.join(allocator: Allocator, separator: []const u8, slices: []const []const u8)
//
//         // try buf.resize(0);
//         // inline for (&blocks) |*block| {
//         //     try block.update();
//         //     try block.print(buf.fixedWriter().any());
//         // }
//         // std.debug.print("buf: {s}\n", .{buf.items});
//         //
//         // std.time.sleep(freq_ms * std.time.ns_per_ms);
//     }
// }
