const LIFECYCLE_ARTIFACTS = [
    'discovery.md',
    'spec.md',
    'design.md',
    'plan.md',
    'implementation.md',
];
export function hasLifecycleArtifacts(fileNames) {
    const files = new Set(fileNames);
    return LIFECYCLE_ARTIFACTS.some((entry) => files.has(entry));
}
export function projectNeedsStateFile(fileNames) {
    const files = new Set(fileNames);
    return !files.has('state.md') && hasLifecycleArtifacts(files);
}
export function projectPlanMarksComplete(planContent) {
    const reviewsHeading = /^## Reviews[ \t]*\r?$/m.exec(planContent);
    if (!reviewsHeading) {
        return false;
    }
    const afterHeading = planContent.slice(reviewsHeading.index + reviewsHeading[0].length);
    const nextSectionIndex = afterHeading.search(/^##(?!#)[ \t]+\S.*\r?$/m);
    const reviewsSection = nextSectionIndex === -1
        ? afterHeading
        : afterHeading.slice(0, nextSectionIndex);
    const finalCodeEvents = reviewsSection
        .split('\n')
        .filter((line) => line.trim().startsWith('|'))
        .map((line) => line
        .split('|')
        .slice(1, -1)
        .map((cell) => cell.trim()))
        .filter(([scope, type]) => scope?.toLowerCase() === 'final' && type?.toLowerCase() === 'code');
    const latestFinalCodeEvent = finalCodeEvents[finalCodeEvents.length - 1];
    return latestFinalCodeEvent?.[2]?.toLowerCase() === 'passed';
}
export function stateLifecycleIsComplete(stateContent) {
    return /^oat_lifecycle:\s*complete$/m.test(stateContent);
}
export function projectNeedsLifecycleComplete(planContent, stateContent) {
    return (projectPlanMarksComplete(planContent) &&
        !stateLifecycleIsComplete(stateContent));
}
export function renderProjectStateTemplate(templateContent, projectName, today) {
    return templateContent
        .replaceAll('{Project Name}', projectName)
        .replaceAll('YYYY-MM-DD', today)
        .replaceAll(/\n?oat_template:\s*true\s*\n/gi, '\n')
        .replaceAll(/\n?oat_template_name:\s*[^\n]*\n/gi, '\n');
}
export function upsertLifecycleCompleteFrontmatter(content) {
    const hasFrontmatter = content.startsWith('---\n');
    if (!hasFrontmatter) {
        return ['---', 'oat_lifecycle: complete', '---', '', content].join('\n');
    }
    const blockEnd = content.indexOf('\n---', 4);
    if (blockEnd === -1) {
        return ['---', 'oat_lifecycle: complete', '---', '', content].join('\n');
    }
    const frontmatter = content.slice(4, blockEnd);
    const rest = content.slice(blockEnd + 4);
    const updatedFrontmatter = /^oat_lifecycle:\s*.+$/m.test(frontmatter)
        ? frontmatter.replace(/^oat_lifecycle:\s*.+$/m, 'oat_lifecycle: complete')
        : `${frontmatter}\noat_lifecycle: complete`;
    return `---\n${updatedFrontmatter}\n---${rest}`;
}
