// tools/manage-hooks.ts — MCP tool handler for manage_hooks (SPEC-071)
import { hooksStore } from '../storage/index.js';
import { dispatchEvent, dryRunDispatch } from '../engine/hooks/core.js';
import { getTemplate, listTemplateNames } from '../engine/hooks/templates.js';
import { generateGitHooks, formatGitHookInstallGuide } from '../engine/hooks/git-hook-generator.js';
import { compactResult, compactError, formatKeyValue, formatTable, formatList, formatConfirmation, } from './output-formatter.js';
// ---------------------------------------------------------------------------
// Operation handlers
// ---------------------------------------------------------------------------
async function handleCreate(params) {
    const { projectId, hook } = params;
    if (!hook?.name || !hook.trigger) {
        return {
            content: [{ type: 'text', text: 'create requires hook.name and hook.trigger' }],
            isError: true,
        };
    }
    const now = new Date().toISOString();
    const newHook = {
        id: `hook-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
        name: hook.name,
        description: hook.description ?? '',
        trigger: hook.trigger,
        filter: hook.filter,
        actions: hook.actions ?? [],
        enabled: hook.enabled ?? true,
        createdAt: now,
        updatedAt: now,
    };
    await hooksStore.saveHook(projectId, newHook);
    return compactResult(`${formatConfirmation(`Hook created: ${newHook.name}`)}\n` +
        formatKeyValue({
            id: newHook.id,
            trigger: newHook.trigger,
            enabled: newHook.enabled,
            actions: newHook.actions.length,
        }));
}
async function handleList(params) {
    const hooks = await hooksStore.getHooks(params.projectId);
    if (hooks.length === 0) {
        return compactResult('No hooks configured. Total: 0');
    }
    return compactResult(formatTable(hooks.map((h) => ({
        id: h.id,
        name: h.name,
        trigger: h.trigger,
        enabled: h.enabled,
        actions: h.actions.length,
    })), ['id', 'name', 'trigger', 'enabled', 'actions'], `Hooks (${hooks.length})`));
}
async function handleDelete(params) {
    const { projectId, hookId } = params;
    if (!hookId) {
        return {
            content: [{ type: 'text', text: 'delete requires hookId' }],
            isError: true,
        };
    }
    await hooksStore.deleteHook(projectId, hookId);
    return compactResult(formatConfirmation(`Hook deleted: ${hookId}`));
}
async function handleEnable(params) {
    const { projectId, hookId } = params;
    if (!hookId) {
        return {
            content: [{ type: 'text', text: 'enable requires hookId' }],
            isError: true,
        };
    }
    const updated = await hooksStore.updateHook(projectId, hookId, { enabled: true });
    return compactResult(`${formatConfirmation(`Hook enabled: ${hookId}`)}\n` +
        formatKeyValue({ name: updated.name, enabled: updated.enabled }));
}
async function handleDisable(params) {
    const { projectId, hookId } = params;
    if (!hookId) {
        return {
            content: [{ type: 'text', text: 'disable requires hookId' }],
            isError: true,
        };
    }
    const updated = await hooksStore.updateHook(projectId, hookId, { enabled: false });
    return compactResult(`${formatConfirmation(`Hook disabled: ${hookId}`)}\n` +
        formatKeyValue({ name: updated.name, enabled: updated.enabled }));
}
async function handleInstallTemplate(params) {
    const { projectId, templateName } = params;
    if (!templateName) {
        const available = listTemplateNames();
        return compactError(`❌ Error: install_template requires templateName\nAvailable: ${available.join(', ')}`);
    }
    const template = getTemplate(templateName);
    if (!template) {
        const available = listTemplateNames();
        return compactError(`❌ Error: Template '${templateName}' not found\nAvailable: ${available.join(', ')}`);
    }
    const now = new Date().toISOString();
    const created = [];
    for (const hookSpec of template.hooks) {
        const newHook = {
            ...hookSpec,
            id: `hook-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
            createdAt: now,
            updatedAt: now,
        };
        await hooksStore.saveHook(projectId, newHook);
        created.push(newHook);
    }
    return compactResult(`${formatConfirmation(`Template '${templateName}' installed: ${created.length} hook(s)`)}\n` +
        formatList(created.map((h) => `${h.name} (${h.trigger})`), 'Installed Hooks'));
}
async function handleDryRun(params) {
    const { projectId, dryRunPayload } = params;
    if (!dryRunPayload) {
        return {
            content: [{ type: 'text', text: 'dry_run requires dryRunPayload' }],
            isError: true,
        };
    }
    const hooks = await hooksStore.getHooks(projectId);
    const results = dryRunDispatch(hooks, dryRunPayload);
    const wouldFire = results.filter((r) => r.wouldFire).length;
    return compactResult(formatKeyValue({
        trigger: dryRunPayload.trigger,
        totalHooks: hooks.length,
        wouldFire,
    }) +
        '\n\n' +
        formatTable(results.map((r) => ({
            hookId: r.hook.id,
            hookName: r.hook.name,
            wouldFire: r.wouldFire,
            reason: r.reason ?? '-',
        })), ['hookId', 'hookName', 'wouldFire', 'reason'], 'Results'));
}
async function handleListLogs(params) {
    const logs = await hooksStore.getHookLogs(params.projectId);
    if (logs.length === 0) {
        return compactResult('No hook logs found. Total: 0');
    }
    return compactResult(formatTable(logs.map((l) => ({
        id: l.id,
        hookName: l.hookName,
        trigger: l.trigger,
        status: l.status,
        executedAt: l.executedAt,
    })), ['id', 'hookName', 'trigger', 'status', 'executedAt'], `Hook Logs (${logs.length})`));
}
// ---------------------------------------------------------------------------
// Main handler
// ---------------------------------------------------------------------------
export async function handleManageHooks(params) {
    try {
        switch (params.operation) {
            case 'create':
                return await handleCreate(params);
            case 'list':
                return await handleList(params);
            case 'delete':
                return await handleDelete(params);
            case 'enable':
                return await handleEnable(params);
            case 'disable':
                return await handleDisable(params);
            case 'install_template':
                return await handleInstallTemplate(params);
            case 'dry_run':
                return await handleDryRun(params);
            case 'list_logs':
                return await handleListLogs(params);
            /* v8 ignore next 10 */
            default:
                return {
                    content: [
                        {
                            type: 'text',
                            text: `❌ Error: Unknown operation: ${String(params.operation)}`,
                        },
                    ],
                    isError: true,
                };
        }
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
            content: [{ type: 'text', text: `Error: ${message}` }],
            isError: true,
        };
    }
}
// ---------------------------------------------------------------------------
// Git hook generation helper
// ---------------------------------------------------------------------------
export function handleGenerateGitHooks(projectId, projectPath) {
    const scripts = generateGitHooks({
        projectId,
        projectPath,
        hookTypes: ['pre-commit', 'post-commit', 'pre-push'],
    });
    const guide = formatGitHookInstallGuide(scripts);
    return {
        content: [{ type: 'text', text: guide }],
    };
}
// ---------------------------------------------------------------------------
// Event dispatch helper (used by other tools to fire hooks)
// ---------------------------------------------------------------------------
export async function dispatchHookEvent(projectId, payload) {
    try {
        const hooks = await hooksStore.getHooks(projectId);
        const logs = dispatchEvent(hooks, payload);
        for (const log of logs) {
            await hooksStore.appendHookLog(projectId, log);
        }
    }
    catch (err) {
        // Fire-and-forget: hook errors must never block the original tool
        const message = err instanceof Error ? err.message : String(err);
        console.error(`[Planu Hooks] dispatchHookEvent failed: ${message}`);
    }
}
//# sourceMappingURL=manage-hooks.js.map