import { readFile } from "node:fs/promises";
import path from "node:path";
import { writeArtifact } from "../../features/artifact-store/index.js";
import { appendEvent, appendToolCall } from "../../features/observability/index.js";
import { auditSeedTextPolicy } from "../../features/policy-audit/index.js";
import { checkSeedReportGate } from "../../features/report-gate/index.js";
import { completePrimaryTasks, runDir, updateRun, writeReport } from "../../features/run-state/index.js";
import { listSubplans, requiredSubplansBlockingFinal } from "../../features/subplan/index.js";
import { listWorkspaceDiffRefs, listWorkspaceWorktreeMerges, unresolvedWorkspaceConflicts, workspacePathWithin } from "../../features/workspace-state/index.js";
import { createId, nowIso } from "../../shared/index.js";
import { LAB_REPRESENTATIVE_AGENT } from "../../agents/identity.js";
import { jsonToolOutput, requireSeedRun } from "./common.js";
export async function executeReportWrite(store, args, context) {
    const run = await requireSeedRun(store, context, args.run_id);
    const shouldEnforceReportGate = args.status === "completed" && store.config.run.review_before_final && !args.bypass_review_gate;
    const shouldEnforcePolicyAudit = args.status === "completed" && store.config.safety.redact_secrets;
    const reportGate = args.status === "completed" ? await checkSeedReportGate(store, run.run_id, { content: args.content, required: shouldEnforceReportGate }) : undefined;
    const policyAudit = args.status === "completed" ? auditSeedTextPolicy({ scope: "final_report.md", content: args.content }) : undefined;
    const reportGateFailed = shouldEnforceReportGate && reportGate?.status === "failed";
    const policyAuditFailed = shouldEnforcePolicyAudit && policyAudit?.status === "failed";
    const workspaceConflicts = args.status === "completed" ? await unresolvedWorkspaceConflicts(store, run.run_id) : [];
    const blockingSubplans = args.status === "completed" ? await requiredSubplansBlockingFinal(store, run.run_id) : [];
    const workspaceDiffs = args.status === "completed" ? await listWorkspaceDiffRefs(store, run.run_id) : [];
    const workspaceMerges = args.status === "completed" ? await listWorkspaceWorktreeMerges(store, run.run_id) : [];
    const acceptedSubplans = args.status === "completed" ? await listSubplans(store, run.run_id) : [];
    const missingDiffSubplans = args.status === "completed"
        ? acceptedSubplans.filter((subplan) => subplan.required_for_final && subplan.status === "accepted" && subplan.write_paths.length > 0 && subplan.diff_refs.length === 0)
        : [];
    const missingDiffRecordSubplans = args.status === "completed"
        ? acceptedSubplans.filter((subplan) => {
            if (!subplan.required_for_final || subplan.status !== "accepted" || subplan.write_paths.length === 0 || subplan.diff_refs.length === 0)
                return false;
            const refs = new Set(subplan.diff_refs);
            return !workspaceDiffs.some((diff) => refs.has(diff.diff_ref) || refs.has(diff.diff_id));
        })
        : [];
    const planDiffMismatches = args.status === "completed"
        ? acceptedSubplans
            .filter((subplan) => subplan.required_for_final && subplan.status === "accepted" && subplan.write_paths.length > 0 && subplan.diff_refs.length > 0)
            .flatMap((subplan) => {
            const refs = new Set(subplan.diff_refs);
            return workspaceDiffs
                .filter((diff) => refs.has(diff.diff_ref) || refs.has(diff.diff_id))
                .flatMap((diff) => diff.paths
                .filter((diffPath) => !subplan.write_paths.some((writePath) => workspacePathWithin(diffPath, writePath)))
                .map((diffPath) => ({ subplan_id: subplan.subplan_id, title: subplan.title, diff_ref: diff.diff_ref, path: diffPath, write_paths: subplan.write_paths })));
        })
        : [];
    const missingWorktreeMergeSubplans = args.status === "completed"
        ? acceptedSubplans.filter((subplan) => {
            if (!subplan.required_for_final || subplan.status !== "accepted" || subplan.workspace_strategy !== "worktree" || subplan.write_paths.length === 0)
                return false;
            const refs = new Set(subplan.diff_refs);
            return !workspaceMerges.some((merge) => merge.subplan_id === subplan.subplan_id &&
                merge.status === "applied" &&
                refs.has(merge.worktree_diff_ref) &&
                Boolean(merge.main_diff_ref && refs.has(merge.main_diff_ref)));
        })
        : [];
    const workspaceConflictsFailed = workspaceConflicts.length > 0;
    const subplansFailed = blockingSubplans.length > 0;
    const subplanDiffsFailed = missingDiffSubplans.length > 0 || missingDiffRecordSubplans.length > 0 || planDiffMismatches.length > 0 || missingWorktreeMergeSubplans.length > 0;
    if (reportGateFailed || policyAuditFailed || workspaceConflictsFailed || subplansFailed || subplanDiffsFailed) {
        const artifactRefs = {};
        if (reportGate) {
            artifactRefs.report_gate = await writeArtifact(store, run.run_id, {
                name: "report-gate",
                extension: ".json",
                content: JSON.stringify(reportGate, null, 2),
            });
        }
        if (policyAudit) {
            artifactRefs.policy_audit = await writeArtifact(store, run.run_id, {
                name: "policy-audit",
                extension: ".json",
                content: JSON.stringify(policyAudit, null, 2),
            });
        }
        const issueCount = (reportGate?.issues.length ?? 0) + (policyAudit?.issues.length ?? 0) + workspaceConflicts.length + blockingSubplans.length + missingDiffSubplans.length + missingDiffRecordSubplans.length + missingWorktreeMergeSubplans.length + planDiffMismatches.length;
        await appendEvent(store, run.run_id, {
            type: "report_completion_gate_failed",
            actor: context.agent ?? LAB_REPRESENTATIVE_AGENT,
            session_id: context.sessionID,
            summary: `Final report completion gate failed with ${issueCount} issue(s)`,
            metadata: {
                artifact_refs: artifactRefs,
                report_gate_issues: reportGate?.issues ?? [],
                policy_audit_issues: policyAudit?.issues ?? [],
                report_gate_warnings: reportGate?.warnings ?? [],
                policy_audit_warnings: policyAudit?.warnings ?? [],
                workspace_conflicts: workspaceConflicts,
                blocking_subplans: blockingSubplans.map((subplan) => ({
                    subplan_id: subplan.subplan_id,
                    title: subplan.title,
                    status: subplan.status,
                    owner_member: subplan.owner_member,
                    verifier_member: subplan.verifier_member,
                })),
                missing_diff_subplans: missingDiffSubplans.map((subplan) => ({
                    subplan_id: subplan.subplan_id,
                    title: subplan.title,
                    owner_member: subplan.owner_member,
                    write_paths: subplan.write_paths,
                })),
                missing_diff_record_subplans: missingDiffRecordSubplans.map((subplan) => ({
                    subplan_id: subplan.subplan_id,
                    title: subplan.title,
                    diff_refs: subplan.diff_refs,
                })),
                missing_worktree_merge_subplans: missingWorktreeMergeSubplans.map((subplan) => ({
                    subplan_id: subplan.subplan_id,
                    title: subplan.title,
                    diff_refs: subplan.diff_refs,
                    merge_owner_member: subplan.merge_owner_member,
                })),
                plan_diff_mismatches: planDiffMismatches,
            },
        });
        await appendToolCall(store, run.run_id, {
            tool_call_id: createId("tool"),
            timestamp_start: nowIso(),
            timestamp_end: nowIso(),
            run_id: run.run_id,
            session_id: context.sessionID,
            agent: context.agent,
            tool_name: "seed_report_write",
            status: "failed",
            output_summary: `Final report completion gate failed with ${issueCount} issue(s)`,
            output_ref: artifactRefs.report_gate ?? artifactRefs.policy_audit,
            evidence_refs: [],
        });
        return jsonToolOutput("SEED report completion gate failed", {
            run_id: run.run_id,
            status: "completion_gate_failed",
            review_gate: reportGate,
            policy_audit: policyAudit,
            workspace_conflicts: workspaceConflicts,
            blocking_subplans: blockingSubplans,
            missing_diff_subplans: missingDiffSubplans,
            missing_diff_record_subplans: missingDiffRecordSubplans,
            missing_worktree_merge_subplans: missingWorktreeMergeSubplans,
            plan_diff_mismatches: planDiffMismatches,
            artifact_refs: artifactRefs,
        });
    }
    const file = await writeReport(store, run.run_id, args.content);
    const artifactRefs = {};
    if (reportGate) {
        artifactRefs.report_gate = await writeArtifact(store, run.run_id, {
            name: "report-gate",
            extension: ".json",
            content: JSON.stringify(reportGate, null, 2),
        });
    }
    if (policyAudit) {
        artifactRefs.policy_audit = await writeArtifact(store, run.run_id, {
            name: "policy-audit",
            extension: ".json",
            content: JSON.stringify(policyAudit, null, 2),
        });
    }
    const completedPrimaryTasks = args.status === "completed" ? await completePrimaryTasks(store, run.run_id, [file]) : [];
    if (args.status)
        await updateRun(store, run.run_id, { status: args.status, completed_at: args.status === "completed" ? nowIso() : undefined });
    if (reportGate) {
        const eventType = reportGate.status === "passed" ? "report_review_gate_passed" : "report_review_gate_bypassed";
        await appendEvent(store, run.run_id, {
            type: eventType,
            actor: context.agent ?? LAB_REPRESENTATIVE_AGENT,
            session_id: context.sessionID,
            summary: reportGate.status === "passed"
                ? `Final report evidence gate passed with ${reportGate.warnings.length} warning(s)`
                : `Final report evidence gate bypassed with ${reportGate.issues.length} issue(s)`,
            metadata: { issues: reportGate.issues, warnings: reportGate.warnings, artifact_ref: artifactRefs.report_gate },
        });
    }
    if (policyAudit) {
        await appendEvent(store, run.run_id, {
            type: "report_policy_audit_passed",
            actor: context.agent ?? LAB_REPRESENTATIVE_AGENT,
            session_id: context.sessionID,
            summary: `Final report policy audit passed with ${policyAudit.warnings.length} warning(s)`,
            metadata: { issues: policyAudit.issues, warnings: policyAudit.warnings, artifact_ref: artifactRefs.policy_audit },
        });
    }
    return jsonToolOutput("SEED report written", {
        run_id: run.run_id,
        path: file,
        completed_primary_tasks: completedPrimaryTasks.map((task) => task.task_id),
        review_gate: reportGate,
        policy_audit: policyAudit,
        artifact_refs: artifactRefs,
    });
}
export async function executeReportCheck(store, args, context) {
    const run = await requireSeedRun(store, context, args.run_id);
    const gate = await checkSeedReportGate(store, run.run_id, { content: args.content, required: store.config.run.review_before_final });
    const artifactRef = await writeArtifact(store, run.run_id, {
        name: "report-gate",
        extension: ".json",
        content: JSON.stringify(gate, null, 2),
    });
    await appendEvent(store, run.run_id, {
        type: "report_review_gate_checked",
        actor: context.agent ?? "seed-agent",
        session_id: context.sessionID,
        summary: `Final report evidence gate checked: ${gate.status}`,
        metadata: { artifact_ref: artifactRef, status: gate.status, issues: gate.issues, warnings: gate.warnings },
    });
    await appendToolCall(store, run.run_id, {
        tool_call_id: createId("tool"),
        timestamp_start: nowIso(),
        timestamp_end: nowIso(),
        run_id: run.run_id,
        session_id: context.sessionID,
        agent: context.agent,
        tool_name: "seed_report_check",
        status: "completed",
        output_summary: `Final report evidence gate checked: ${gate.status}`,
        output_ref: artifactRef,
        evidence_refs: gate.report.cited_evidence_refs,
    });
    return jsonToolOutput("SEED report gate", { run_id: run.run_id, gate, artifact_ref: artifactRef });
}
export async function executeReportExport(store, args, context) {
    const run = await requireSeedRun(store, context, args.run_id);
    const file = path.join(runDir(store, run.run_id), "final_report.md");
    return jsonToolOutput("SEED report export", {
        run_id: run.run_id,
        path: file,
        content: args.include_content ? await readFile(file, "utf8") : undefined,
    });
}
//# sourceMappingURL=reporting.js.map