type ExtensionState = Record<string, unknown>;
type StreamState = Record<string, ExtensionState>;

function cloneValue<T>(value: T): T {
    if (value === null || value === undefined) {
        return value;
    }

    if (typeof value === "object") {
        return structuredClone(value);
    }

    return value;
}

export class HubStateRegistry {
    private readonly state: Record<string, StreamState> = {};

    public getState<T>(
        streamId: string,
        extensionId: string,
        key: string,
        defaultValue: T
    ): T {
        const stream = this.state[streamId];
        const extension = stream?.[extensionId];
        const value = extension?.[key] as T | undefined;

        if (value === undefined) {
            return cloneValue(defaultValue);
        }

        return cloneValue(value);
    }

    public setState<T>(
        streamId: string,
        extensionId: string,
        key: string,
        value: T
    ): void {
        const stream = (this.state[streamId] ??= {});
        const extension = (stream[extensionId] ??= {});
        extension[key] = cloneValue(value);
    }
}
