const std = @import("std");

const models = @import("../../../models/root.zig");

const Self = @This();

allocator: std.mem.Allocator,
client_map: std.StringHashMap(models.DisplayClient),
lock: std.Thread.RwLock = .{},

pub fn init(allocator: std.mem.Allocator) Self {
    return .{
        .allocator = allocator,
        .client_map = std.StringHashMap(models.DisplayClient).init(allocator),
    };
}

pub fn deinit(self: *Self) void {
    self.client_map.deinit();
}

pub fn add(self: *Self, client: *const models.DisplayClient) !void {
    self.lock.lock();
    defer self.lock.unlock();

    const name = client.nameSlice();

    if (self.client_map.getPtr(name)) |val| {
        val.channel_id = client.channel_id;
    } else {
        try self.client_map.put(name, .{
            .name = client.name,
            .name_len = client.name_len,
            .channel_id = client.channel_id,
        });
    }
}

pub fn remove(self: *Self, name: []const u8) bool {
    self.lock.lockShared();
    defer self.lock.unlockShared();

    return self.client_map.remove(name);
}

pub fn exists(self: *Self, name: []const u8) !bool {
    self.lock.lock();
    defer self.lock.unlock();

    return self.client_map.get(name) != null;
}

pub fn get(self: *Self, name: []const u8) ?models.DisplayClient {
    self.lock.lock();
    defer self.lock.unlock();

    return self.client_map.get(name) orelse return null;

    // const copy: server.models.DisplayClient = .{
    //     .name = try allocator.dupe(u8, client.name),
    //     .channel_id = client.channel_id,
    // };

    // return server.ResultArena(server.models.DisplayClient){
    //     .arena = arena,
    //     .value = copy,
    // };
}
