import { nowIso, readJsonFile, withFileLock, writeJsonFile } from "../../shared/index.js";
import { LAB_REPRESENTATIVE_AGENT } from "../../agents/identity.js";
import { appendEvent } from "../observability/index.js";
import { listTeamInbox } from "./mailbox.js";
import { listTeamTasks } from "./task-board.js";
import { ensureTeamRuntime, teamCleanupPath, teamRuntimePath } from "./store.js";
const terminalTaskStatuses = new Set(["completed", "cancelled"]);
export async function completeTeamRuntime(store, runId, options = {}) {
    const runtime = await ensureTeamRuntime(store, runId);
    const tasks = await listTeamTasks(store, runId);
    const openTaskIds = tasks.filter((task) => !terminalTaskStatuses.has(task.status)).map((task) => task.team_task_id);
    const unreadEntries = await Promise.all(runtime.members.map(async (member) => [
        member.name,
        (await listTeamInbox(store, runId, member.name, { includeAcknowledged: false })).length,
    ]));
    const unreadByMember = Object.fromEntries(unreadEntries);
    const unreadMessageCount = Object.values(unreadByMember).reduce((sum, count) => sum + count, 0);
    if (openTaskIds.length > 0 && !options.allowOpenTasks) {
        throw new Error(`team cleanup blocked by open task(s): ${openTaskIds.join(",")}`);
    }
    if (unreadMessageCount > 0 && !options.allowUnreadMessages) {
        const unreadSummary = Object.entries(unreadByMember)
            .filter(([, count]) => count > 0)
            .map(([member, count]) => `${member}:${count}`)
            .join(",");
        throw new Error(`team cleanup blocked by unread message(s): ${unreadSummary}`);
    }
    const timestamp = nowIso();
    const completedRuntime = await withFileLock(teamRuntimePath(store, runId), async () => {
        const current = (await readJsonFile(teamRuntimePath(store, runId))) ?? runtime;
        const next = {
            ...current,
            status: "completed",
            updated_at: timestamp,
            members: current.members.map((member) => ({
                ...member,
                status: "done",
                last_seen_at: timestamp,
            })),
        };
        await writeJsonFile(teamRuntimePath(store, runId), next);
        return next;
    });
    const report = {
        version: 1,
        run_id: runId,
        created_at: timestamp,
        runtime_status_before: runtime.status,
        runtime_status_after: completedRuntime.status,
        members: completedRuntime.members.map((member) => ({
            name: member.name,
            role: member.role,
            status: member.status,
            last_seen_at: member.last_seen_at,
        })),
        tasks_by_status: countBy(tasks.map((task) => task.status)),
        open_task_ids: openTaskIds,
        unread_by_member: unreadByMember,
        unread_message_count: unreadMessageCount,
        warnings: [
            ...(openTaskIds.length > 0 ? [`cleanup completed with open task(s): ${openTaskIds.join(",")}`] : []),
            ...(unreadMessageCount > 0 ? ["cleanup completed with unread team message(s)"] : []),
        ],
    };
    await writeJsonFile(teamCleanupPath(store, runId), report);
    await appendEvent(store, runId, {
        type: "team_runtime_completed",
        actor: store.config.default_run_agent ?? LAB_REPRESENTATIVE_AGENT,
        summary: `Team runtime completed with ${openTaskIds.length} open task(s) and ${unreadMessageCount} unread message(s).`,
        metadata: {
            open_task_count: openTaskIds.length,
            unread_message_count: unreadMessageCount,
            cleanup_path: "team/cleanup.json",
        },
    });
    return { runtime: completedRuntime, report };
}
function countBy(values) {
    const counts = {};
    for (const value of values)
        counts[value] = (counts[value] ?? 0) + 1;
    return counts;
}
//# sourceMappingURL=cleanup.js.map