// SPEC-452 — Generates TDD test stubs from spec acceptance criteria
import { readFile, writeFile, mkdir } from 'node:fs/promises';
import { join, dirname } from 'node:path';
const SECTION_RE = /^###\s+(.+)$/;
function sanitizeTestName(text) {
    return text.replace(/[`'"]/g, '').trim();
}
export function parseSpecCriteria(specContent) {
    const stubs = [];
    const lines = specContent.split('\n');
    let currentSection = 'General';
    let criterionIndex = 0;
    for (const line of lines) {
        const sectionMatch = SECTION_RE.exec(line);
        if (sectionMatch) {
            currentSection = sectionMatch[1] ?? 'General';
            continue;
        }
        const match = /^- \[[ x]\]\s+(.+)$/.exec(line);
        if (match) {
            criterionIndex++;
            const text = match[1] ?? '';
            const id = `AC-${criterionIndex}`;
            stubs.push({
                criterionId: id,
                criterionText: sanitizeTestName(text),
                section: currentSection,
                testCode: `  it('${id}: ${sanitizeTestName(text)}', () => {\n    // TODO: implement test from acceptance criteria\n    expect.fail('TDD stub — not implemented');\n  });`,
            });
        }
    }
    return stubs;
}
export function buildStubFileContent(specId, stubs) {
    const sections = new Map();
    for (const stub of stubs) {
        const existing = sections.get(stub.section) ?? [];
        existing.push(stub);
        sections.set(stub.section, existing);
    }
    const parts = [
        `// TDD stubs auto-generated from ${specId} acceptance criteria`,
        `// Implement each test before writing production code`,
        ``,
        `import { describe, it, expect } from 'vitest';`,
        ``,
        `describe('${specId} — TDD stubs', () => {`,
    ];
    for (const [section, sectionStubs] of sections) {
        parts.push(`  describe('${sanitizeTestName(section)}', () => {`);
        for (const stub of sectionStubs) {
            parts.push(stub.testCode);
            parts.push('');
        }
        parts.push('  });');
        parts.push('');
    }
    parts.push('});');
    parts.push('');
    return parts.join('\n');
}
export async function generateTestStubs(specId, projectPath) {
    const specDir = join(projectPath, 'planu', 'specs');
    const { glob } = await import('glob');
    const matches = await glob(`${specDir}/${specId}-*/spec.md`);
    const specFile = matches[0];
    if (!specFile) {
        return { specId, stubs: [], fileContent: '', outputPath: '' };
    }
    const content = await readFile(specFile, 'utf-8');
    const stubs = parseSpecCriteria(content);
    if (stubs.length === 0) {
        return { specId, stubs: [], fileContent: '', outputPath: '' };
    }
    const fileContent = buildStubFileContent(specId, stubs);
    const outputPath = join(dirname(specFile), 'test-stubs.ts');
    await mkdir(dirname(outputPath), { recursive: true });
    await writeFile(outputPath, fileContent, 'utf-8');
    return { specId, stubs, fileContent, outputPath };
}
//# sourceMappingURL=stub-generator.js.map