/**
 * Hook health tracking and analysis
 *
 * Analyzes hook execution logs to determine health status:
 * - OK: >90% success rate, no recent consecutive failures
 * - DEGRADED: 50-90% success rate OR 3+ warnings in last 10 executions
 * - FAILED: <50% success rate OR 3+ consecutive failures
 * - UNKNOWN: No execution data available
 *
 * @example
 * ```typescript
 * const tracker = new HookHealthTracker();
 * const logger = new HookLogger('.specweave/logs/hooks');
 * const logs = await logger.readLogs('session-start', 100);
 *
 * const health = tracker.analyze('session-start', logs);
 * console.log(`Status: ${health.status}`);
 * console.log(`Success rate: ${(health.successRate * 100).toFixed(1)}%`);
 * ```
 */
export class HookHealthTracker {
    constructor() {
        this.WINDOW_HOURS = 24;
        this.DEGRADED_THRESHOLD = 0.5;
        this.OK_THRESHOLD = 0.9;
        this.CONSECUTIVE_FAILURE_THRESHOLD = 3;
    }
    /**
     * Analyze hook health from execution logs
     *
     * @param hookName - Name of the hook
     * @param logs - Log entries (should be sorted by timestamp, most recent first)
     * @param referenceTime - Reference time for 24h window (default: now)
     * @returns Health analysis
     */
    analyze(hookName, logs, referenceTime) {
        if (logs.length === 0) {
            return {
                hookName,
                status: 'UNKNOWN',
                successRate: 0,
                avgDuration: 0,
                lastRun: null,
                totalExecutions: 0,
                consecutiveFailures: 0,
                recommendations: ['No execution data available']
            };
        }
        // Filter logs to 24h window
        const now = referenceTime || new Date();
        const windowStart = new Date(now.getTime() - this.WINDOW_HOURS * 60 * 60 * 1000);
        const recentLogs = logs
            .filter(log => {
            if (!log.timestamp)
                return false;
            const logTime = new Date(log.timestamp);
            return logTime >= windowStart && logTime <= now;
        })
            .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
        if (recentLogs.length === 0) {
            return {
                hookName,
                status: 'UNKNOWN',
                successRate: 0,
                avgDuration: 0,
                lastRun: logs[0]?.timestamp || null,
                totalExecutions: 0,
                consecutiveFailures: 0,
                recommendations: ['No recent executions in last 24h']
            };
        }
        // Calculate metrics
        const successCount = recentLogs.filter(l => l.status === 'success').length;
        const successRate = successCount / recentLogs.length;
        const durations = recentLogs.filter(l => l.duration !== undefined).map(l => l.duration);
        const avgDuration = durations.length > 0
            ? durations.reduce((sum, d) => sum + d, 0) / durations.length
            : 0;
        const lastRun = recentLogs[0]?.timestamp ?? null;
        // Count consecutive failures from most recent
        const consecutiveFailures = recentLogs.findIndex(log => log.status !== 'error');
        const actualConsecutiveFailures = consecutiveFailures === -1 ? recentLogs.length : consecutiveFailures;
        // Determine status
        let status;
        if (actualConsecutiveFailures >= this.CONSECUTIVE_FAILURE_THRESHOLD || successRate < this.DEGRADED_THRESHOLD) {
            status = 'FAILED';
        }
        else if (successRate < this.OK_THRESHOLD) {
            status = 'DEGRADED';
        }
        else {
            const recentWarnings = recentLogs.slice(0, 10).filter(l => l.status === 'warning').length;
            status = recentWarnings >= 3 ? 'DEGRADED' : 'OK';
        }
        // Generate recommendations
        const recommendations = [];
        if (status === 'FAILED') {
            recommendations.push('Run `specweave hooks health` to diagnose issues');
            if (actualConsecutiveFailures >= 3) {
                recommendations.push('Multiple consecutive failures detected');
            }
            recommendations.push('Check `.specweave/logs/hooks/${hookName}.log` for details');
        }
        else if (status === 'DEGRADED') {
            recommendations.push('Run `specweave hooks health` to identify problems');
            if (avgDuration > 5000) {
                recommendations.push('Hook execution is slow (>5s) - may timeout');
            }
        }
        return {
            hookName,
            status,
            successRate,
            avgDuration: Math.round(avgDuration),
            lastRun,
            totalExecutions: recentLogs.length,
            consecutiveFailures: actualConsecutiveFailures,
            recommendations
        };
    }
    /**
     * Analyze health for multiple hooks
     * @returns Array of health analyses sorted by severity, then by name
     */
    analyzeAll(hooks) {
        return Array.from(hooks.entries())
            .map(([hookName, logs]) => this.analyze(hookName, logs))
            .sort((a, b) => {
            const statusDiff = HookHealthTracker.STATUS_ORDER[a.status] - HookHealthTracker.STATUS_ORDER[b.status];
            return statusDiff !== 0 ? statusDiff : a.hookName.localeCompare(b.hookName);
        });
    }
}
HookHealthTracker.STATUS_ORDER = {
    FAILED: 0,
    DEGRADED: 1,
    OK: 2,
    UNKNOWN: 3
};
//# sourceMappingURL=hook-health-tracker.js.map