"use strict";
// SPDX-License-Identifier: AGPL-3.0-or-later
// Copyright (C) 2024-2026 Gracker (Chris)
// This file is part of SmartPerfetto. See LICENSE for details.
Object.defineProperty(exports, "__esModule", { value: true });
exports.HookRegistry = void 0;
exports.getHookRegistry = getHookRegistry;
exports.setHookRegistry = setHookRegistry;
exports.resetHookRegistry = resetHookRegistry;
/**
 * Hook Registry
 *
 * 中央钩子注册表，管理所有生命周期钩子的注册和执行
 */
const hookTypes_1 = require("./hookTypes");
const hookContext_1 = require("./hookContext");
// =============================================================================
// Hook Registry
// =============================================================================
class HookRegistry {
    constructor(config = {}) {
        this.handlers = new Map();
        this.config = { ...hookTypes_1.DEFAULT_HOOK_REGISTRY_CONFIG, ...config };
        // 注册初始中间件
        if (this.config.middleware) {
            for (const middleware of this.config.middleware) {
                this.use(middleware);
            }
        }
    }
    // ===========================================================================
    // Registration Methods
    // ===========================================================================
    /**
     * 注册单个钩子处理器
     */
    register(eventType, phase, handler) {
        const key = this.getKey(eventType, phase);
        if (!this.handlers.has(key)) {
            this.handlers.set(key, []);
        }
        const handlers = this.handlers.get(key);
        handlers.push(handler);
        // 按优先级排序 (优先级小的先执行)
        handlers.sort((a, b) => a.priority - b.priority);
        // 返回取消注册函数
        return () => this.unregister(eventType, phase, handler.name);
    }
    /**
     * 取消注册钩子处理器
     */
    unregister(eventType, phase, handlerName) {
        const key = this.getKey(eventType, phase);
        const handlers = this.handlers.get(key);
        if (!handlers)
            return false;
        const index = handlers.findIndex((h) => h.name === handlerName);
        if (index === -1)
            return false;
        handlers.splice(index, 1);
        return true;
    }
    /**
     * 注册中间件 (批量注册到多个事件/阶段)
     */
    use(middleware) {
        const unregisterFns = [];
        for (const eventType of middleware.events) {
            for (const phase of middleware.phases) {
                const handler = {
                    name: `${middleware.name}:${eventType}:${phase}`,
                    priority: middleware.priority,
                    handler: middleware.handler,
                    enabled: middleware.enabled,
                };
                const unregister = this.register(eventType, phase, handler);
                unregisterFns.push(unregister);
            }
        }
        // 返回批量取消注册函数
        return () => {
            for (const fn of unregisterFns) {
                fn();
            }
        };
    }
    // ===========================================================================
    // Execution Methods
    // ===========================================================================
    /**
     * 执行钩子链
     */
    async execute(event, context) {
        // 如果 hooks 被禁用，直接返回继续
        if (!this.config.enabled) {
            return hookTypes_1.HOOK_CONTINUE;
        }
        const key = this.getKey(event.type, event.phase);
        const handlers = this.handlers.get(key);
        if (!handlers || handlers.length === 0) {
            return hookTypes_1.HOOK_CONTINUE;
        }
        // 创建或使用提供的上下文
        const hookContext = context ?? (0, hookContext_1.createHookContext)(event.sessionId, event.data && 'traceId' in event.data ? event.data.traceId : '');
        let lastResult = hookTypes_1.HOOK_CONTINUE;
        let modifiedData = event.data;
        for (const handler of handlers) {
            // 跳过禁用的处理器
            if (handler.enabled === false) {
                continue;
            }
            // 检查过滤条件
            if (handler.filter && !handler.filter(event)) {
                continue;
            }
            // 检查上下文是否已中止
            if (hookContext.aborted) {
                return {
                    continue: false,
                    error: new Error(hookContext.abortReason || 'Hook chain aborted'),
                };
            }
            try {
                // 使用可能被修改的数据创建事件副本
                const eventWithModifiedData = {
                    ...event,
                    data: modifiedData,
                };
                // 执行处理器 (带超时)
                const result = await this.executeWithTimeout(handler.handler(eventWithModifiedData, hookContext), this.config.defaultTimeout || 5000);
                lastResult = result;
                // 如果返回了修改后的数据，更新它
                if (result.modifiedData !== undefined) {
                    modifiedData = result.modifiedData;
                }
                // 如果不继续，中断链
                if (!result.continue) {
                    return {
                        ...result,
                        modifiedData,
                    };
                }
            }
            catch (error) {
                console.error(`[HookRegistry] Handler "${handler.name}" failed:`, error);
                if (!this.config.continueOnError) {
                    return {
                        continue: false,
                        error: error instanceof Error ? error : new Error(String(error)),
                    };
                }
                // 继续执行下一个处理器
            }
        }
        return {
            ...lastResult,
            modifiedData,
        };
    }
    /**
     * 便捷方法：执行 pre 阶段钩子
     */
    async executePre(eventType, sessionId, data, context) {
        const event = {
            type: eventType,
            phase: 'pre',
            timestamp: Date.now(),
            sessionId,
            data,
        };
        return this.execute(event, context);
    }
    /**
     * 便捷方法：执行 post 阶段钩子
     */
    async executePost(eventType, sessionId, data, context) {
        const event = {
            type: eventType,
            phase: 'post',
            timestamp: Date.now(),
            sessionId,
            data,
        };
        return this.execute(event, context);
    }
    // ===========================================================================
    // Query Methods
    // ===========================================================================
    /**
     * 获取已注册的处理器数量
     */
    getHandlerCount(eventType, phase) {
        if (eventType && phase) {
            const key = this.getKey(eventType, phase);
            return this.handlers.get(key)?.length ?? 0;
        }
        let count = 0;
        for (const handlers of this.handlers.values()) {
            count += handlers.length;
        }
        return count;
    }
    /**
     * 获取所有注册的事件类型
     */
    getRegisteredEvents() {
        const events = [];
        for (const key of this.handlers.keys()) {
            const [type, phase] = key.split(':');
            events.push({ type, phase });
        }
        return events;
    }
    /**
     * 清除所有处理器
     */
    clear() {
        this.handlers.clear();
    }
    /**
     * 启用/禁用 hooks
     */
    setEnabled(enabled) {
        this.config.enabled = enabled;
    }
    /**
     * 检查是否启用
     */
    isEnabled() {
        return this.config.enabled;
    }
    // ===========================================================================
    // Private Methods
    // ===========================================================================
    getKey(eventType, phase) {
        return `${eventType}:${phase}`;
    }
    async executeWithTimeout(promise, timeoutMs) {
        return Promise.race([
            promise,
            new Promise((_, reject) => setTimeout(() => reject(new Error('Hook handler timeout')), timeoutMs)),
        ]);
    }
}
exports.HookRegistry = HookRegistry;
// =============================================================================
// Singleton Instance
// =============================================================================
let _globalRegistry = null;
/**
 * 获取全局 Hook 注册表
 */
function getHookRegistry() {
    if (!_globalRegistry) {
        _globalRegistry = new HookRegistry();
    }
    return _globalRegistry;
}
/**
 * 设置全局 Hook 注册表 (用于测试或自定义配置)
 */
function setHookRegistry(registry) {
    _globalRegistry = registry;
}
/**
 * 重置全局 Hook 注册表
 */
function resetHookRegistry() {
    _globalRegistry = null;
}
//# sourceMappingURL=hookRegistry.js.map