// tools/start-hooks.ts — Start file watcher + hook engine (SPEC-130)
import { HookEngine } from '../engine/hooks/hook-engine.js';
import { EventBus } from '../engine/hooks/event-bus.js';
import { FileWatcher } from '../engine/hooks/file-watcher.js';
import { ConfigLoader } from '../engine/hooks/config-loader.js';
import { Debouncer } from '../engine/hooks/debouncer.js';
// ---------------------------------------------------------------------------
// Singleton state
// ---------------------------------------------------------------------------
let engineInstance = null;
let watcherInstance = null;
let debouncerInstance = null;
let configLoaderInstance = null;
/**
 * Get the current engine instance (for testing/internal use).
 */
export function getEngineInstance() {
    return engineInstance;
}
/**
 * Get the current watcher instance (for testing/internal use).
 */
export function getWatcherInstance() {
    return watcherInstance;
}
// ---------------------------------------------------------------------------
// Start hooks
// ---------------------------------------------------------------------------
export async function handleStartHooks(args) {
    // Idempotent — if already running, return status
    if (engineInstance?.status().running) {
        const status = engineInstance.status();
        return {
            content: [
                {
                    type: 'text',
                    text: JSON.stringify({
                        message: 'Hook engine already running',
                        ...status,
                    }, null, 2),
                },
            ],
        };
    }
    const projectPath = args.projectPath;
    const enabledHooks = args.hooks ?? ['on-save', 'on-create', 'on-delete'];
    // Load config
    configLoaderInstance = new ConfigLoader(projectPath);
    const config = await configLoaderInstance.load();
    // Create event bus and engine
    const eventBus = new EventBus();
    engineInstance = new HookEngine(eventBus);
    // Create file watcher
    watcherInstance = new FileWatcher({
        rootDir: projectPath,
        include: config.hooks['on-save']?.include,
        exclude: config.hooks['on-save']?.exclude,
    });
    // Create debouncer
    debouncerInstance = new Debouncer((event) => {
        const hookType = mapEventToHookType(event);
        if (hookType && enabledHooks.includes(hookType)) {
            void engineInstance?.dispatch(event, hookType);
        }
    }, {
        debounceMs: config.debounceMs,
        rateLimitPerFileMs: config.rateLimitPerFileMs,
    });
    // Wire watcher -> debouncer
    watcherInstance.on('change', (event) => {
        eventBus.emitEvent('file:change', {
            path: event.path,
            type: event.type,
            timestamp: event.timestamp,
        });
        debouncerInstance?.push(event);
    });
    // Start watching config for live reload
    configLoaderInstance.startWatching();
    // Start engine and watcher
    engineInstance.start();
    watcherInstance.start();
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify({
                    message: 'Hook engine started',
                    projectPath,
                    enabledHooks,
                    config: {
                        debounceMs: config.debounceMs,
                        rateLimitPerFileMs: config.rateLimitPerFileMs,
                    },
                }, null, 2),
            },
        ],
    };
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function mapEventToHookType(event) {
    switch (event.type) {
        case 'modify':
            return 'on-save';
        case 'create':
            return 'on-create';
        case 'delete':
            return 'on-delete';
        default:
            return null;
    }
}
// ---------------------------------------------------------------------------
// Stop hooks
// ---------------------------------------------------------------------------
export async function handleStopHooks(_args) {
    await Promise.resolve(); // Ensure async for safeLicensed wrapper
    if (!engineInstance) {
        return {
            content: [{ type: 'text', text: JSON.stringify({ message: 'Hook engine not running' }) }],
        };
    }
    engineInstance.stop();
    watcherInstance?.close();
    debouncerInstance?.dispose();
    configLoaderInstance?.close();
    const message = 'Hook engine stopped and resources cleaned up';
    engineInstance = null;
    watcherInstance = null;
    debouncerInstance = null;
    configLoaderInstance = null;
    return {
        content: [{ type: 'text', text: JSON.stringify({ message }) }],
    };
}
// ---------------------------------------------------------------------------
// Hook status
// ---------------------------------------------------------------------------
export async function handleHookStatus() {
    await Promise.resolve(); // Ensure async for safeLicensed wrapper
    if (!engineInstance) {
        return {
            content: [
                {
                    type: 'text',
                    text: JSON.stringify({
                        running: false,
                        activeHooks: [],
                        pendingEvents: 0,
                        telemetry: {},
                        eventHistory: 0,
                    }),
                },
            ],
        };
    }
    const status = engineInstance.status();
    const eventBus = engineInstance.getEventBus();
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify({
                    ...status,
                    eventHistory: eventBus.getFullHistory().length,
                }, null, 2),
            },
        ],
    };
}
// ---------------------------------------------------------------------------
// Configure hooks
// ---------------------------------------------------------------------------
export async function handleConfigureHooks(args) {
    if (!configLoaderInstance) {
        // Not running — just load and report current config
        const loader = new ConfigLoader(args.projectPath);
        const config = await loader.load();
        loader.close();
        return {
            content: [
                {
                    type: 'text',
                    text: JSON.stringify({
                        message: 'Hook engine not running. Current config:',
                        config,
                    }, null, 2),
                },
            ],
        };
    }
    // Reload config
    const config = await configLoaderInstance.load();
    return {
        content: [
            {
                type: 'text',
                text: JSON.stringify({
                    message: 'Configuration reloaded',
                    config,
                    engineRunning: engineInstance?.status().running ?? false,
                }, null, 2),
            },
        ],
    };
}
//# sourceMappingURL=start-hooks.js.map