import { readFile } from 'node:fs/promises';
import { isAbsolute, join } from 'node:path';
import { extractCriteria, extractListItems, extractSection, } from '../../engine/validator/extractors.js';
import { stripFrontmatter } from '../../engine/frontmatter-parser.js';
import { readEvidenceArtifacts } from '../../engine/evidence-gates/artifact-reader.js';
import { checkLifecycleEvidenceGate } from '../../engine/evidence-gates/lifecycle-gate.js';
import { buildSpecEvidenceIndex } from '../../engine/evidence-index/index-builder.js';
import { checkDoneDriftContract } from '../../engine/evidence-index/done-drift.js';
import { parseTechnicalReferenceGroundingRecords } from '../../engine/spec-grounding/contract.js';
/** SPEC-1054: BDD/SDD lifecycle evidence gate. */
export async function checkLifecycleEvidenceTransitionGate(args) {
    const [criteriaResult, artifacts] = await Promise.all([
        extractLifecycleGateCriteriaAndBody(args.spec, args.projectPath),
        readEvidenceArtifacts({
            spec: args.spec,
            projectId: args.projectId,
            specId: args.specId,
            projectPath: args.projectPath,
        }),
    ]);
    const { criteria, body } = criteriaResult;
    const result = checkLifecycleEvidenceGate({
        transition: args.transition,
        spec: args.spec,
        criteria,
        artifacts,
    });
    if (args.transition === 'done') {
        const index = await buildSpecEvidenceIndex({
            specId: args.specId,
            criteria,
            artifacts,
            projectPath: args.projectPath,
        });
        const groundedTechnicalPaths = body
            ? parseTechnicalReferenceGroundingRecords(body).map((record) => record.path)
            : [];
        result.issues.push(...checkDoneDriftContract({ index, groundedTechnicalPaths }));
    }
    if (result.issues.length === 0) {
        return null;
    }
    return evidenceGateError({
        specId: args.specId,
        transition: args.transition,
        issues: result.issues.map((issue) => ({
            code: issue.code,
            message: issue.message,
        })),
        requiredContractKinds: result.requiredContractKinds,
    });
}
async function extractLifecycleGateCriteriaAndBody(spec, projectPath) {
    const specPath = isAbsolute(spec.specPath) || !projectPath ? spec.specPath : join(projectPath, spec.specPath);
    try {
        const raw = await readFile(specPath, 'utf-8');
        const body = stripFrontmatter(raw);
        const acceptanceCriteria = extractSection(body, 'acceptance criteria', 'criterios de aceptaci');
        if (acceptanceCriteria) {
            const items = extractListItems(acceptanceCriteria);
            if (items.length > 0) {
                return { criteria: [...new Set(items)], body: raw };
            }
        }
    }
    catch {
        // Fall back to the broader validator extractor when the canonical file is unavailable.
    }
    return { criteria: await extractCriteria(spec), body: null };
}
function evidenceGateError(args) {
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify({
                    error: 'lifecycle_evidence_gate_failed',
                    message: `BDD/SDD evidence gate blocked ${args.transition}.`,
                    specId: args.specId,
                    transition: args.transition,
                    issues: args.issues,
                    requiredContractKinds: args.requiredContractKinds,
                    fixHint: 'Add the missing evidence artifact to the external Planu project data handoff store, then retry the transition. Do not create JSON files under planu/specs/<spec>/.',
                }, null, 2),
            },
        ],
        isError: true,
        structuredContent: {
            error: 'lifecycle_evidence_gate_failed',
            code: 422,
            sddConstitutionRuleId: args.transition === 'done' ? 'sdd.done-evidence-required' : 'sdd.grounded-contract',
            context: {
                specId: args.specId,
                transition: args.transition,
                issues: args.issues,
                requiredContractKinds: args.requiredContractKinds,
            },
            fixHint: 'Add discovery.json, task-plan.json, traceability-matrix.json, and contract-validation-*.json to the external Planu handoff store as required for this transition. Spec folders remain spec.md-only.',
        },
    };
}
//# sourceMappingURL=evidence-gate.js.map