const std = @import("std");
// const bufzilla = @import("bufzilla");

const shared = @import("shared");
const server = @import("server.zig");
const enet   = @import("c.zig").enet;

pub fn spawn(self: *shared.chunk.Chunk, allocator: std.mem.Allocator, host: *enet.ENetHost, comptime T: type, value: T) !shared.entity.id {
    std.debug.assert(value.id == shared.entity.INVALID_ID);

    const id = server.next_entity_id;
    server.next_entity_id += 1;

    const ptr = try allocator.create(T);
    errdefer allocator.destroy(ptr);

    ptr.* = value;
    ptr.id = id;

    const ref = shared.entity.makeRef(T, ptr);

    try self.entities.append(allocator, ref);

    _ = host;


    // std.log.info("{}", .{shared.protocol.makeSpawnMessage(T, entity)});

    // serialize entity
    // const msg = shared.protocol.makeSpawnMessage(T, entity);

    // const data = fixed.buffered();
    // const packet = enet.enet_packet_create(data.ptr, data.len + 1, enet.ENET_PACKET_FLAG_RELIABLE);

    // enet.enet_host_broadcast(host, 0, packet);

    return ptr.id;
}

pub fn broadcastChanges(chunk: *shared.chunk.Chunk, allocator: std.mem.Allocator, host: *enet.ENetHost) !void {
    var aw = try std.ArrayList(u8).initCapacity(allocator, 128);
    defer aw.deinit(allocator);

    var writer = shared.bits.BitWriter.init(&aw);

    for (chunk.entities.items) |e| {
        const msg = shared.protocol_v1.makeUpdateMessage(e);
        try writer.serialize(allocator, msg);
    }

    const encoded = writer.written();
    
    const packet = enet.enet_packet_create(encoded.ptr, encoded.len, enet.ENET_PACKET_FLAG_RELIABLE);

    enet.enet_host_broadcast(host, 0, packet);
}
