// tools/hook-generator-handler.ts — Handlers for Dynamic Hook Generator tools (SPEC-416)
import { detectStack } from '../engine/project-scanner/index.js';
import { getPrimaryAiTool } from '../engine/ai-tool-detector/index.js';
import { getHookSectionsForStack } from '../engine/hook-generator/stack-hook-templates.js';
import { getAIHookSections } from '../engine/hook-generator/ai-hook-templates.js';
import { previewHooks, mergeHooks } from '../engine/hook-generator/hook-merger.js';
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
/** Maps DetectedStack fields to canonical stack tokens used in templates. */
async function resolveStackTokens(projectPath) {
    const detected = await detectStack(projectPath);
    const tokens = [];
    const langMap = {
        typescript: 'typescript',
        javascript: 'eslint',
        python: 'python',
        go: 'go',
    };
    const lang = langMap[detected.language];
    if (lang !== undefined) {
        tokens.push(lang);
    }
    if (detected.testRunner === 'vitest') {
        tokens.push('vitest');
    }
    else if (detected.testRunner === 'jest') {
        tokens.push('jest');
    }
    if (detected.linter !== null) {
        tokens.push('eslint');
    }
    if (detected.formatter !== null) {
        tokens.push('prettier');
    }
    // Deduplicate
    return [...new Set(tokens)];
}
/** Formats MergeResult[] into a human-readable summary. */
function formatMergeResults(results, dryRun) {
    const prefix = dryRun ? '[DRY RUN] ' : '';
    const lines = [`${prefix}Hook generation complete.\n`];
    for (const r of results) {
        lines.push(`**${r.filePath}**`);
        if (r.sectionsAdded.length > 0) {
            lines.push(`  Added: ${r.sectionsAdded.join(', ')}`);
        }
        if (r.sectionsUpdated.length > 0) {
            lines.push(`  Updated: ${r.sectionsUpdated.join(', ')}`);
        }
        if (r.sectionsSkipped.length > 0) {
            lines.push(`  Skipped (already present): ${r.sectionsSkipped.join(', ')}`);
        }
        if (r.sectionsAdded.length === 0 &&
            r.sectionsUpdated.length === 0 &&
            r.sectionsSkipped.length === 0) {
            lines.push(`  No changes.`);
        }
    }
    return lines.join('\n');
}
// ---------------------------------------------------------------------------
// Handlers
// ---------------------------------------------------------------------------
/** generate_hooks_for_stack — detect stack + AI tool, generate and merge hooks */
export async function handleGenerateHooksForStack(input) {
    const { projectPath, dryRun = false } = input;
    let stackTokens;
    if (input.stack !== undefined && input.stack.length > 0) {
        stackTokens = input.stack;
    }
    else {
        stackTokens = await resolveStackTokens(projectPath);
    }
    let aiTool;
    if (input.aiTool !== undefined) {
        aiTool = input.aiTool;
    }
    else {
        const detected = getPrimaryAiTool(projectPath);
        aiTool = detected.toolId;
    }
    const sections = [
        ...getHookSectionsForStack(stackTokens),
        ...getAIHookSections(aiTool),
    ];
    if (sections.length === 0) {
        return {
            content: [
                {
                    type: 'text',
                    text: 'No hook sections matched the detected stack. Pass `stack` explicitly to override.',
                },
            ],
        };
    }
    const results = await mergeHooks(projectPath, sections, dryRun);
    const summary = formatMergeResults(results, dryRun);
    return {
        content: [{ type: 'text', text: summary }],
        structuredContent: { results, stackTokens, aiTool, dryRun },
    };
}
/** preview_hooks — show what would change without writing */
export async function handlePreviewHooks(input) {
    const { projectPath } = input;
    let stackTokens;
    if (input.stack !== undefined && input.stack.length > 0) {
        stackTokens = input.stack;
    }
    else {
        stackTokens = await resolveStackTokens(projectPath);
    }
    const sections = getHookSectionsForStack(stackTokens);
    if (sections.length === 0) {
        return {
            content: [{ type: 'text', text: 'No hook sections matched the detected stack.' }],
        };
    }
    const previews = await previewHooks(projectPath, sections);
    const lines = ['## Hook Preview\n'];
    for (const p of previews) {
        lines.push(`### ${p.phase} → \`${p.filePath}\``);
        lines.push(`- File exists: ${p.currentContent !== null ? 'yes' : 'no'}`);
        lines.push(`- Would modify: ${p.wouldModify ? 'yes' : 'no'}`);
        if (p.conflicts.length > 0) {
            lines.push(`- Already present (will update): ${p.conflicts.join(', ')}`);
        }
        if (p.proposedAdditions.length > 0) {
            lines.push(`- New additions: ${p.proposedAdditions.map((s) => s.id).join(', ')}`);
        }
        lines.push('');
    }
    return {
        content: [{ type: 'text', text: lines.join('\n') }],
        structuredContent: { previews, stackTokens },
    };
}
/** merge_hooks — apply explicit sections into hook files */
export async function handleMergeHooks(input) {
    const { projectPath, sections, dryRun = false } = input;
    if (sections.length === 0) {
        return {
            content: [{ type: 'text', text: 'No sections provided — nothing to merge.' }],
        };
    }
    const results = await mergeHooks(projectPath, sections, dryRun);
    const summary = formatMergeResults(results, dryRun);
    return {
        content: [{ type: 'text', text: summary }],
        structuredContent: { results, dryRun },
    };
}
//# sourceMappingURL=hook-generator-handler.js.map