// SPEC-597-EXEMPT: canonical mapping (npm-package↔framework, keyword catalogue)
// — must enumerate framework names by design; no detection logic to migrate.
// engine/execution-plan/plan-utils.ts — Utilities for execution plan generation
// Critical path analysis, parallelization detection, and file inference helpers.
import { readFile } from 'node:fs/promises';
import { readSpecTechnicalSection } from '../spec-format/read-technical-section.js';
// --- Critical path & parallelization ---
export function determineCriticalPath(phases) {
    const path = [];
    for (const phase of phases) {
        const firstStep = phase.steps[0];
        /* v8 ignore next 3 -- defensive: steps always have at least one entry */
        if (!firstStep) {
            continue;
        }
        const longestStep = phase.steps.reduce((longest, step) => (step.estimatedMinutes > longest.estimatedMinutes ? step : longest), firstStep);
        path.push(`[${phase.name}] ${longestStep.title} (${longestStep.estimatedMinutes}min)`);
    }
    return path;
}
export function findParallelizable(phases) {
    const groups = [];
    for (const phase of phases) {
        const depGroups = new Map();
        for (const step of phase.steps) {
            const depKey = step.dependsOn.sort((a, b) => a - b).join(',');
            const group = depGroups.get(depKey) ?? [];
            group.push(step.title);
            depGroups.set(depKey, group);
        }
        for (const group of depGroups.values()) {
            if (group.length > 1) {
                groups.push(group);
            }
        }
    }
    return groups;
}
// --- File inference helpers (SRP: each infers one type of file) ---
export function inferDataLayerFiles(spec, knowledge) {
    const base = knowledge.architecture.layers.find((l) => l.name === 'infrastructure')?.directories[0] ?? 'src';
    return [`${base}/${spec.slug}-repository.ts`];
}
export function inferServiceFiles(spec, knowledge) {
    const base = knowledge.architecture.layers.find((l) => l.name === 'application')?.directories[0] ?? 'src';
    return [`${base}/${spec.slug}-service.ts`];
}
export function inferApiFiles(spec, knowledge) {
    const firstContract = knowledge.apiContracts[0];
    const apiType = firstContract ? firstContract.type : 'rest';
    const base = apiType === 'trpc' ? 'src/server/routers' : 'src/routes';
    return [`${base}/${spec.slug}.ts`];
}
export function inferPageFiles(spec, knowledge) {
    const framework = (knowledge.framework ?? '').toLowerCase();
    if (framework.includes('next')) {
        return [`app/${spec.slug}/page.tsx`];
    }
    if (framework.includes('nuxt')) {
        return [`pages/${spec.slug}.vue`];
    }
    return [`src/pages/${spec.slug}.tsx`];
}
export function inferComponentFiles(spec, knowledge) {
    const ext = (knowledge.framework ?? '').toLowerCase().includes('vue') ? 'vue' : 'tsx';
    return [`src/components/${spec.slug}/${spec.slug}.${ext}`];
}
// --- Spec content reader ---
export async function readSpecContent(spec) {
    let content = `${spec.title} ${spec.type} ${spec.scope} ${spec.target} ${spec.tags.join(' ')}`;
    try {
        if (spec.specPath) {
            content += ' ' + (await readFile(spec.specPath, 'utf-8'));
        }
    }
    catch {
        /* file not available */
    }
    content += ' ' + (await readSpecTechnicalSection(spec));
    return content;
}
//# sourceMappingURL=plan-utils.js.map