import { HubStateRegistry } from "../hub/stateRegistry";

function assert(condition: boolean, message: string): void {
    if (!condition) {
        throw new Error(message);
    }
}

async function main(): Promise<void> {
    const registry = new HubStateRegistry();

    const defaultCounter = registry.getState<number>("stream-a", "polls", "counter", 0);
    assert(defaultCounter === 0, "Expected default value when key is missing.");

    registry.setState("stream-a", "polls", "counter", 1);
    registry.setState("stream-a", "system-status", "counter", 9);
    registry.setState("stream-b", "polls", "counter", 5);

    const streamAPolls = registry.getState<number>("stream-a", "polls", "counter", 0);
    const streamASystem = registry.getState<number>("stream-a", "system-status", "counter", 0);
    const streamBPolls = registry.getState<number>("stream-b", "polls", "counter", 0);

    assert(streamAPolls === 1, "Expected stream-a/polls value to be isolated.");
    assert(streamASystem === 9, "Expected extension separation within the same stream.");
    assert(streamBPolls === 5, "Expected stream separation for same extension key.");

    const objectDefault = { nested: { enabled: false } };
    const loadedDefault = registry.getState("stream-c", "merged-chat", "config", objectDefault);
    loadedDefault.nested.enabled = true;
    const loadedDefaultAgain = registry.getState("stream-c", "merged-chat", "config", objectDefault);
    assert(
        loadedDefaultAgain.nested.enabled === false,
        "Expected default object to be cloned and not mutated by caller."
    );

    registry.setState("stream-a", "polls", "settings", { duration: 30 });
    const settings = registry.getState("stream-a", "polls", "settings", { duration: 0 }) as {
        duration: number;
    };
    settings.duration = 999;
    const settingsAgain = registry.getState("stream-a", "polls", "settings", { duration: 0 }) as {
        duration: number;
    };
    assert(
        settingsAgain.duration === 30,
        "Expected stored object state to be cloned on read to protect internal state."
    );

    console.log(
        JSON.stringify(
            {
                ok: true,
                values: {
                    streamAPolls,
                    streamASystem,
                    streamBPolls
                }
            },
            null,
            2
        )
    );
}

main().catch((error: unknown) => {
    const message = error instanceof Error ? error.message : String(error);
    console.error(message);
    process.exit(1);
});
