/**
 * @deprecated [DC-3] 无运行时消费方。保留供未来任务恢复实现。
 */
import fs from "node:fs/promises";
import fss from "node:fs";
import path from "node:path";
import { debug } from "../core/logger.js";
/** 活跃状态集合（classifying 纳入扫描但标记为不可恢复） */
const ACTIVE_STATUSES = [
    "classifying",
    "expanding",
    "executing",
    "verifying",
    "retrying",
    "learning",
    "reworking",
];
/**
 * 扫描工作区状态目录，恢复最后活跃的工单。
 *
 * 增强能力:
 * - recoverable: 标识任务是否实际可恢复（classifying / corrupt → 不可恢复）
 * - needs_human_confirm: 多个活跃工单时返回 true，附带候选列表
 * - orphan_leases_cleaned: 清理无对应任务文件的孤儿租约
 *
 * @param taskContext - 任务上下文管理器
 * @returns 唤醒结果
 */
export async function scanAndResume(taskContext) {
    debug("工作区恢复", "scanAndResume() 开始执行");
    // 清理孤儿租约
    const orphanCleaned = cleanupOrphanLeases(taskContext);
    const recent = await taskContext.listRecent(100);
    const activeTasks = recent.filter((t) => ACTIVE_STATUSES.includes(t.status));
    if (activeTasks.length === 0) {
        debug("工作区恢复", "无活跃工单, total=${recent.length}");
        return {
            resumed: false,
            broadcast: "工作区干净，无中断工单。可以开始新任务",
            total_tasks: recent.length,
            active_tasks: 0,
            needs_human_confirm: false,
            orphan_leases_cleaned: orphanCleaned,
        };
    }
    // 多个活跃工单 → 需要人工选择
    if (activeTasks.length > 1) {
        debug("工作区恢复", "发现 ${activeTasks.length} 个活跃工单，需人工选择");
        const candidates = [];
        for (const t of activeTasks) {
            const ctx = await taskContext.load(t.task_id);
            const phaseHint = ctx ? taskContext.getResumeHint(ctx) : "未知状态";
            candidates.push({
                task_id: t.task_id,
                intent: t.intent,
                status: t.status,
                created_at: t.created_at,
                phase_hint: phaseHint,
            });
        }
        return {
            resumed: false,
            broadcast: `发现 ${activeTasks.length} 个活跃工单，请选择要恢复的工单:\n` +
                candidates.map((c, i) => `  ${i + 1}. [${c.task_id}] ${c.intent} (${c.status})`).join("\n"),
            total_tasks: recent.length,
            active_tasks: activeTasks.length,
            needs_human_confirm: true,
            active_candidates: candidates,
            orphan_leases_cleaned: orphanCleaned,
        };
    }
    // 单个活跃工单 → 自动恢复
    const latestActive = activeTasks[0];
    const ctx = await taskContext.load(latestActive.task_id);
    if (!ctx) {
        debug("工作区恢复", "工单 ${latestActive.task_id} 无法加载上下文");
        return {
            resumed: false,
            broadcast: `发现活跃工单 ${latestActive.task_id}，但无法加载（可能文件损坏）`,
            total_tasks: recent.length,
            active_tasks: activeTasks.length,
            needs_human_confirm: false,
            orphan_leases_cleaned: orphanCleaned,
        };
    }
    // 检查可恢复性
    const { recoverable, reason } = checkRecoverable(ctx);
    const phaseHint = taskContext.getResumeHint(ctx);
    if (!recoverable) {
        debug("工作区恢复", "工单 ${ctx.task_id} 不可恢复, reason=${reason}");
        return {
            resumed: false,
            task: {
                task_id: ctx.task_id,
                intent: ctx.intent,
                status: ctx.status,
                created_at: ctx.created_at,
                phase_hint: phaseHint,
                recoverable: false,
                unrecoverable_reason: reason,
            },
            broadcast: `工单 ${ctx.task_id} (${ctx.intent}) 状态为 ${ctx.status}，不可自动恢复 (${reason})。建议取消后重新创建。`,
            total_tasks: recent.length,
            active_tasks: activeTasks.length,
            needs_human_confirm: false,
            orphan_leases_cleaned: orphanCleaned,
        };
    }
    debug("工作区恢复", "工单 ${ctx.task_id} (${ctx.intent}) 可恢复, status=${ctx.status}");
    // 构造播报消息
    const changedFiles = ctx.execution?.changed_files?.length ?? 0;
    const attemptCount = ctx.execution?.attempt_count ?? 0;
    let progressDetail = "";
    if (ctx.classification) {
        progressDetail += `任务类型: ${ctx.classification.task_type}，风险: ${ctx.classification.risk}，策略: ${ctx.classification.strategy}`;
    }
    if (changedFiles > 0) {
        progressDetail += ` | 已修改 ${changedFiles} 个文件`;
    }
    if (attemptCount > 0) {
        progressDetail += ` | 第 ${attemptCount} 次尝试`;
    }
    const broadcast = [
        `⚡ 检测到 ${activeTasks.length} 个中断工单，已自动恢复最新的:`,
        ``,
        `工单: ${ctx.intent}`,
        `状态: ${ctx.status} → ${phaseHint}`,
        `创建时间: ${ctx.created_at}`,
        progressDetail ? `进度: ${progressDetail}` : "",
        ``,
        `请继续执行上述操作，或输入 "sf_status action=cancel task_id=${ctx.task_id}" 取消此工单`,
    ].filter(Boolean).join("\n");
    // 将此工单设为当前活跃
    const stateDir = taskContext.getStateDir();
    const pointerPath = path.join(stateDir, "current-task.json");
    await fs.writeFile(pointerPath, JSON.stringify({ task_id: ctx.task_id }));
    return {
        resumed: true,
        task: {
            task_id: ctx.task_id,
            intent: ctx.intent,
            status: ctx.status,
            created_at: ctx.created_at,
            phase_hint: phaseHint,
            recoverable: true,
        },
        broadcast,
        total_tasks: recent.length,
        active_tasks: activeTasks.length,
        needs_human_confirm: false,
        orphan_leases_cleaned: orphanCleaned,
    };
}
/**
 * 清理超期活跃任务 — advisory 报告，不自动 fail。
 * @param taskContext - 任务上下文管理器
 * @param maxAgeMs - 最大存活时间（毫秒），默认 7 天
 * @returns 清理报告（不执行任何状态变更）
 */
export async function cleanupStaleTasks(taskContext, maxAgeMs = 7 * 24 * 60 * 60 * 1000) {
    debug("工作区恢复", "cleanupStaleTasks() 开始, maxAge=${Math.round(maxAgeMs / 3600000)}h");
    const recent = await taskContext.listRecent(100);
    const now = Date.now();
    const stale = [];
    for (const t of recent) {
        if (!ACTIVE_STATUSES.includes(t.status))
            continue;
        const updatedAt = t.updated_at ?? t.created_at;
        const age = now - new Date(updatedAt).getTime();
        if (age > maxAgeMs) {
            stale.push({
                task_id: t.task_id,
                intent: t.intent,
                status: t.status,
                created_at: t.created_at,
                age_ms: age,
                advisory: `task ${t.task_id} (${t.intent}) has been active for ${Math.round(age / 3600000)}h, exceeds threshold ${Math.round(maxAgeMs / 3600000)}h`,
            });
        }
    }
    debug("工作区恢复", "cleanupStaleTasks 完成, stale=${stale.length}");
    return {
        stale_tasks: stale,
        stale_count: stale.length,
        recommendation: stale.length > 0
            ? `发现 ${stale.length} 个超期活跃工单，建议人工审查后取消或完成。不自动执行任何状态变更。`
            : "无超期活跃工单",
    };
}
function checkRecoverable(ctx) {
    if (ctx.status === "classifying") {
        return { recoverable: false, reason: "classifying" };
    }
    return { recoverable: true };
}
function cleanupOrphanLeases(taskContext) {
    const stateDir = taskContext.getStateDir();
    const leaseStore = taskContext.getScopeLease();
    const activeLeases = leaseStore.getActiveLeases();
    let cleaned = 0;
    for (const lease of activeLeases) {
        const taskFile = path.join(stateDir, `${lease.task_id}.json`);
        if (!fss.existsSync(taskFile)) {
            leaseStore.release(lease.task_id);
            cleaned++;
        }
    }
    return cleaned;
}
//# sourceMappingURL=workspace_resumer.js.map