"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsRouter = void 0;
const errors_1 = require("@yinuo-ngm/errors");
class WsRouter {
    constructor() {
        this.handlers = new Map();
    }
    register(handler) {
        this.handlers.set(handler.topic, handler);
    }
    handleRaw(ctx, raw) {
        let msg = null;
        try {
            const text = typeof raw === "string" ? raw : raw?.toString?.() ?? "";
            msg = JSON.parse(text);
        }
        catch {
            ctx.send(this.err(errors_1.GlobalErrorCodes.BAD_JSON, "Invalid JSON"));
            return;
        }
        if (!msg || typeof msg !== "object" || !("op" in msg)) {
            ctx.send(this.err(errors_1.GlobalErrorCodes.BAD_MSG, "Invalid message"));
            return;
        }
        if (msg.op === "ping") {
            ctx.send({ op: "pong", ts: Date.now() });
            return;
        }
        if (msg.op === "resize") {
            const topic = msg.topic;
            const h = this.handlers.get(topic);
            if (!h || !h.resize) {
                ctx.send(this.err(errors_1.GlobalErrorCodes.OP_NOT_SUPPORTED, `resize not supported on topic: ${String(topic)}`, { topic }));
                return;
            }
            try {
                return void h.resize(ctx, msg);
            }
            catch (e) {
                ctx.send(this.err(errors_1.GlobalErrorCodes.HANDLER_FAILED, e?.message ?? "handler failed", { topic, op: msg.op }));
                return;
            }
        }
        if (msg.op === "sub" || msg.op === "unsub") {
            const topic = msg.topic;
            const h = this.handlers.get(topic);
            if (!h) {
                ctx.send(this.err(errors_1.GlobalErrorCodes.TOPIC_NOT_FOUND, `Unknown topic: ${String(topic)}`, { topic }));
                return;
            }
            try {
                if (msg.op === "sub")
                    return void h.sub(ctx, msg);
                return void h.unsub(ctx, msg);
            }
            catch (e) {
                ctx.send(this.err(errors_1.GlobalErrorCodes.HANDLER_FAILED, e?.message ?? "handler failed", { topic, op: msg.op }));
            }
            return;
        }
        ctx.send(this.err(errors_1.GlobalErrorCodes.OP_NOT_FOUND, `Unknown op: ${msg.op}`));
    }
    err(code, message, details) {
        return { op: "error", code, message, details, ts: Date.now() };
    }
}
exports.WsRouter = WsRouter;
