// tools/manage-hooks.ts — MCP tool handler for manage_hooks (SPEC-071)
import { hooksStore } from '../storage/index.js';
import { dispatchEvent, dryRunDispatch, getTemplate, listTemplateNames, generateGitHooks, formatGitHookInstallGuide, } from '../engine/hooks/index.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 {
        content: [
            {
                type: 'text',
                text: JSON.stringify({ created: true, hook: newHook }, null, 2),
            },
        ],
    };
}
async function handleList(params) {
    const hooks = await hooksStore.getHooks(params.projectId);
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify({
                    count: hooks.length,
                    hooks: hooks.map((h) => ({
                        id: h.id,
                        name: h.name,
                        trigger: h.trigger,
                        enabled: h.enabled,
                        actionCount: h.actions.length,
                    })),
                }, null, 2),
            },
        ],
    };
}
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 {
        content: [{ type: 'text', text: JSON.stringify({ deleted: true, hookId }, null, 2) }],
    };
}
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 {
        content: [{ type: 'text', text: JSON.stringify({ enabled: true, hook: updated }, null, 2) }],
    };
}
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 {
        content: [{ type: 'text', text: JSON.stringify({ disabled: true, hook: updated }, null, 2) }],
    };
}
async function handleInstallTemplate(params) {
    const { projectId, templateName } = params;
    if (!templateName) {
        const available = listTemplateNames();
        return {
            content: [
                {
                    type: 'text',
                    text: JSON.stringify({ error: 'install_template requires templateName', available }, null, 2),
                },
            ],
            isError: true,
        };
    }
    const template = getTemplate(templateName);
    if (!template) {
        const available = listTemplateNames();
        return {
            content: [
                {
                    type: 'text',
                    text: JSON.stringify({ error: `Template '${templateName}' not found`, available }, null, 2),
                },
            ],
            isError: true,
        };
    }
    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 {
        content: [
            {
                type: 'text',
                text: JSON.stringify({ template: templateName, hooksInstalled: created.length, hooks: created }, null, 2),
            },
        ],
    };
}
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);
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify({
                    trigger: dryRunPayload.trigger,
                    totalHooks: hooks.length,
                    wouldFire: results.filter((r) => r.wouldFire).length,
                    results: results.map((r) => ({
                        hookId: r.hook.id,
                        hookName: r.hook.name,
                        wouldFire: r.wouldFire,
                        reason: r.reason,
                    })),
                }, null, 2),
            },
        ],
    };
}
async function handleListLogs(params) {
    const logs = await hooksStore.getHookLogs(params.projectId);
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify({ count: logs.length, logs }, null, 2),
            },
        ],
    };
}
// ---------------------------------------------------------------------------
// 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);
        }
    }
    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