// engine/ai-cost-estimator/spec-loader.ts — Loads spec content and counts acceptance criteria.
// Extracted from core.ts to keep file sizes within limits.
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';
/**
 * Reads spec content from a sdd/specs directory.
 * Tries to find the spec directory by matching specId prefix.
 */
export async function loadSpecContent(specId) {
    // Try modern location first, fallback to legacy
    let specsRoot = 'planu/specs';
    try {
        const { access: fsAccess } = await import('node:fs/promises');
        await fsAccess(specsRoot);
    }
    catch {
        specsRoot = 'docs/sdd/specs';
    }
    const { readdir } = await import('node:fs/promises');
    let specDir = null;
    try {
        const topEntries = await readdir(specsRoot);
        // Try flat layout first: planu/specs/SPEC-069-name/ or docs/sdd/specs/SPEC-069-name/
        const flatMatch = topEntries.find((e) => e.startsWith(specId));
        if (flatMatch) {
            specDir = join(specsRoot, flatMatch);
        }
        else {
            // Try nested layout: planu/specs/{feature}/SPEC-069-name/
            for (const group of topEntries) {
                try {
                    const groupEntries = await readdir(join(specsRoot, group));
                    const nestedMatch = groupEntries.find((e) => e.startsWith(specId));
                    if (nestedMatch) {
                        specDir = join(specsRoot, group, nestedMatch);
                        break;
                    }
                }
                catch {
                    // Not a directory — skip
                }
            }
        }
    }
    catch {
        throw new Error(`Spec directory not found at "${specsRoot}". ` +
            'Make sure you are running from the project root.');
    }
    if (!specDir) {
        throw new Error(`Spec "${specId}" not found in "${specsRoot}". ` + 'Check that the spec directory exists.');
    }
    const parts = [];
    // Try modern names first, fallback to legacy — only read one of each pair
    for (const [modern, legacy] of [
        ['spec.md', 'HU.md'],
        ['technical.md', 'FICHA-TECNICA.md'],
    ]) {
        let found = false;
        for (const filename of [modern, legacy]) {
            if (found) {
                break;
            }
            try {
                const content = await readFile(join(specDir, filename), 'utf-8');
                parts.push(content);
                found = true;
            }
            catch {
                // File not present — try next
            }
        }
    }
    if (parts.length === 0) {
        throw new Error(`Spec "${specId}" has no spec files in "${specDir}". ` +
            'Cannot estimate without spec content.');
    }
    return { content: parts.join('\n\n'), specDir };
}
/** Counts acceptance criteria (lines starting with "- [ ]" or "- [x]") in spec content. */
export function countAcceptanceCriteria(specContent) {
    const matches = specContent.match(/^- \[[ xX]\]/gm);
    return matches?.length ?? 0;
}
/** Reads average tokens per call from usage.json if available. */
export async function readUsageAvgTokensPerCall() {
    try {
        const { readFile: rf } = await import('node:fs/promises');
        const raw = await rf('data/global/usage.json', 'utf-8');
        /* v8 ignore start */
        const log = JSON.parse(raw);
        if (log.events.length === 0) {
            return undefined;
        }
        // Usage events don't track token counts — return undefined to use defaults
        return undefined;
        /* v8 ignore stop */
    }
    catch {
        return undefined;
    }
}
//# sourceMappingURL=spec-loader.js.map