"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTaskTopicHandler = createTaskTopicHandler;
const errors_1 = require("@yinuo-ngm/errors");
const keyOfTask = (taskId) => `task:${taskId}`;
function createTaskTopicHandler(deps, getAllClients) {
    return {
        topic: "task",
        async sub(ctx, msg) {
            const taskId = String(msg?.taskId ?? "").trim();
            const tail = Number(msg?.tail ?? 0);
            if (!taskId) {
                ctx.send({ op: "error", code: errors_1.CoreErrorCodes.TASK_ID_REQUIRED, message: "taskId is required", ts: Date.now() });
                return;
            }
            ctx.addSub("task", keyOfTask(taskId));
            let snap;
            if (deps.getTaskSnapshotByTaskId) {
                snap = await deps.getTaskSnapshotByTaskId(taskId) ?? undefined;
                if (snap) {
                    const m = {
                        op: "task.event",
                        type: "snapshot",
                        payload: snap,
                        ts: Date.now(),
                    };
                    ctx.send(m);
                }
            }
            if (snap?.runId && deps.getTaskTailLogsByRun && tail > 0) {
                const entries = await deps.getTaskTailLogsByRun(snap.runId, tail);
                for (const e of entries ?? []) {
                    const m = {
                        op: "task.output",
                        payload: {
                            taskId: taskId,
                            runId: snap.runId,
                            stream: (e?.level === "warn" || e?.level === "error") ? "stderr" : "stdout",
                            text: String(e?.text ?? ""),
                        },
                        ts: e?.ts ?? Date.now(),
                    };
                    ctx.send(m);
                }
            }
        },
        resize(ctx, msg) {
            const taskId = msg.taskId;
            const cols = Number(msg.cols);
            const rows = Number(msg.rows);
            if (!taskId || !Number.isFinite(cols) || !Number.isFinite(rows))
                return;
            const c = Math.max(2, Math.floor(cols));
            const r = Math.max(1, Math.floor(rows));
            deps.resizeRun?.(taskId, c, r);
        },
        unsub(ctx, msg) {
            const taskId = String(msg?.taskId ?? "").trim();
            if (!taskId)
                return;
            ctx.delSub("task", keyOfTask(taskId));
        },
        pushOutput(payload) {
            const m = { op: "task.output", payload, ts: Date.now() };
            for (const c of getAllClients())
                if (c.hasSub("task", keyOfTask(payload.taskId)))
                    c.send(m);
        },
        pushEvent(type, payload) {
            const m = { op: "task.event", type, payload, ts: Date.now() };
            for (const c of getAllClients())
                if (c.hasSub("task", keyOfTask(payload.taskId)))
                    c.send(m);
        },
    };
}
