import path from "node:path";
import { markStaleBackgroundTasks } from "../background-state/index.js";
import { deliverQueuedAgentMessages } from "../message-bus/index.js";
import { appendEvent } from "../observability/index.js";
import { createRunStore, getActiveRun, getRun } from "../run-state/index.js";
import { nowIso } from "../../shared/index.js";
import { checkLabMeetingDeadline, readLabMeetingState } from "./index.js";
import { requestLabRepresentativeMeetingReport } from "../../plugin/lab-meeting-control.js";
const supervisors = new Map();
export function startLabMeetingSupervisor(directory, config, options = {}) {
    const key = path.resolve(directory);
    const existing = supervisors.get(key);
    if (existing)
        return existing;
    const store = createRunStore(directory, config);
    const pollIntervalMs = Math.max(1_000, Math.floor(options.poll_interval_ms ?? 60_000));
    const now = options.now ?? nowIso;
    let timer;
    let running = false;
    const supervisor = {
        directory: key,
        poll_interval_ms: pollIntervalMs,
        async pollOnce() {
            if (running)
                return;
            running = true;
            try {
                await pollActiveRun(store, now(), options.delivery_context);
            }
            finally {
                running = false;
            }
        },
        stop() {
            if (timer)
                clearInterval(timer);
            timer = undefined;
            supervisors.delete(key);
        },
    };
    supervisors.set(key, supervisor);
    if (options.start_timer !== false) {
        timer = setInterval(() => {
            void supervisor.pollOnce();
        }, pollIntervalMs);
        timer.unref?.();
    }
    return supervisor;
}
export function stopLabMeetingSupervisor(directory) {
    const supervisor = supervisors.get(path.resolve(directory));
    if (!supervisor)
        return false;
    supervisor.stop();
    return true;
}
export function listLabMeetingSupervisors() {
    return [...supervisors.values()];
}
async function pollActiveRun(store, timestamp, deliveryContext) {
    const active = await getActiveRun(store);
    if (!active)
        return;
    try {
        const stale = await markStaleBackgroundTasks(store, active.run_id, {
            now: timestamp,
            staleAfterMinutes: store.config.budget.stale_worker_minutes,
            reason: "Lab Meeting supervisor detected a stale background worker.",
        });
        if (stale.length) {
            await appendEvent(store, active.run_id, {
                type: "background_workers_marked_stale",
                actor: store.config.default_run_agent,
                summary: `${stale.length} background worker(s) marked stale.`,
                metadata: { background_ids: stale.map((task) => task.background_id) },
            });
        }
        const currentMeetingState = await readLabMeetingState(store, active.run_id);
        const meetingCheck = currentMeetingState?.status === "wrap_up"
            ? await checkLabMeetingDeadline(store, active.run_id, {
                now: timestamp,
                reason: "lab_meeting_supervisor",
            })
            : { enabled: currentMeetingState?.enabled ?? false, triggered: false, state: currentMeetingState };
        if (deliveryContext && meetingCheck.triggered) {
            const run = await getRun(store, active.run_id);
            const report = await requestLabRepresentativeMeetingReport(deliveryContext, store, active.run_id, {
                sessionId: run?.root_session_id,
                source: "lab_meeting_supervisor",
            });
            await appendEvent(store, active.run_id, {
                type: "lab_meeting_supervisor_report_tick",
                actor: store.config.default_run_agent,
                summary: `Lab Meeting representative report request ${report.status}.`,
                metadata: report,
            });
        }
        const meetingState = meetingCheck.state ?? await readLabMeetingState(store, active.run_id);
        if (deliveryContext && (!meetingState || meetingState.status === "scheduled")) {
            const delivered = await deliverQueuedAgentMessages(store, active.run_id, deliveryContext, {
                maxDeliveries: 3,
                now: timestamp,
            });
            if (delivered.delivered || delivered.mailbox_only || delivered.failed) {
                await appendEvent(store, active.run_id, {
                    type: "lab_meeting_message_delivery_tick",
                    actor: store.config.default_run_agent,
                    summary: `message delivery tick delivered=${delivered.delivered} mailbox_only=${delivered.mailbox_only} failed=${delivered.failed}`,
                    metadata: delivered,
                });
            }
        }
    }
    catch (error) {
        await appendEvent(store, active.run_id, {
            type: "lab_meeting_supervisor_failed",
            actor: store.config.default_run_agent,
            summary: error instanceof Error ? error.message.slice(0, 240) : String(error).slice(0, 240),
        }).catch(() => undefined);
    }
}
//# sourceMappingURL=supervisor.js.map