"use strict";
/**
 * Health Check System
 * Production monitoring and health endpoints
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.healthEndpoints = exports.globalHealthChecker = void 0;
const memory_manager_1 = require("../utils/memory-manager");
const error_handler_1 = require("../utils/error-handler");
class HealthChecker {
    startTime;
    requestCount = 0;
    successfulRequests = 0;
    failedRequests = 0;
    responseTimes = [];
    constructor() {
        this.startTime = Date.now();
    }
    /**
     * Perform comprehensive health check
     */
    async checkHealth() {
        const checks = [];
        const startTime = Date.now();
        // Memory health check
        checks.push(await this.checkMemoryHealth());
        // Error rate check
        checks.push(await this.checkErrorRate());
        // Performance check
        checks.push(await this.checkPerformance());
        // Dependencies check (file system, etc.)
        checks.push(await this.checkDependencies());
        // Calculate summary
        const passing = checks.filter((c) => c.status === 'pass').length;
        const failing = checks.filter((c) => c.status === 'fail').length;
        const warnings = checks.filter((c) => c.status === 'warn').length;
        // Determine overall status
        let status;
        if (failing > 0) {
            status = 'unhealthy';
        }
        else if (warnings > 0) {
            status = 'degraded';
        }
        else {
            status = 'healthy';
        }
        return {
            status,
            timestamp: new Date().toISOString(),
            uptime: Date.now() - this.startTime,
            version: process.env.npm_package_version || '1.0.0',
            checks,
            summary: {
                total: checks.length,
                passing,
                failing,
                warnings,
            },
        };
    }
    /**
     * Get detailed monitoring metrics
     */
    getMetrics() {
        const memoryUsage = memory_manager_1.globalMemoryManager.getMemoryStats();
        const errorStats = error_handler_1.globalErrorHandler.getErrorStatistics();
        const cpuUsage = process.cpuUsage();
        return {
            memory: {
                heapUsed: Math.round(memoryUsage.current.heapUsed / (1024 * 1024)),
                heapTotal: Math.round(memoryUsage.current.heapTotal / (1024 * 1024)),
                external: Math.round(memoryUsage.current.external / (1024 * 1024)),
                rss: Math.round(memoryUsage.current.rss / (1024 * 1024)),
                percentUsed: Math.round((memoryUsage.current.heapUsed / memoryUsage.current.heapTotal) * 100),
            },
            performance: {
                uptime: Date.now() - this.startTime,
                cpuUsage,
                eventLoopDelay: this.measureEventLoopDelay(),
            },
            errors: {
                total: errorStats.totalErrors,
                last24h: this.getErrorsLast24h(),
                byCategory: errorStats.byCategory,
                bySeverity: errorStats.bySeverity,
            },
            requests: {
                total: this.requestCount,
                successful: this.successfulRequests,
                failed: this.failedRequests,
                averageResponseTime: this.getAverageResponseTime(),
            },
        };
    }
    /**
     * Record request metrics
     */
    recordRequest(success, responseTime) {
        this.requestCount++;
        if (success) {
            this.successfulRequests++;
        }
        else {
            this.failedRequests++;
        }
        this.responseTimes.push(responseTime);
        // Keep only last 1000 response times
        if (this.responseTimes.length > 1000) {
            this.responseTimes.shift();
        }
    }
    /**
     * Check memory health
     */
    async checkMemoryHealth() {
        const start = Date.now();
        try {
            const memoryUsage = memory_manager_1.globalMemoryManager.getMemoryStats();
            const percentUsed = Math.round((memoryUsage.current.heapUsed / memoryUsage.current.heapTotal) * 100);
            let status;
            let message;
            if (percentUsed < 70) {
                status = 'pass';
                message = `Memory usage normal (${percentUsed.toFixed(1)}%)`;
            }
            else if (percentUsed < 85) {
                status = 'warn';
                message = `Memory usage elevated (${percentUsed.toFixed(1)}%)`;
            }
            else {
                status = 'fail';
                message = `Memory usage critical (${percentUsed.toFixed(1)}%)`;
            }
            return {
                name: 'memory',
                status,
                message,
                duration: Date.now() - start,
                metadata: {
                    heapUsedMB: Math.round(memoryUsage.current.heapUsed / (1024 * 1024)),
                    heapTotalMB: Math.round(memoryUsage.current.heapTotal / (1024 * 1024)),
                    percentUsed,
                },
            };
        }
        catch (error) {
            return {
                name: 'memory',
                status: 'fail',
                message: `Memory check failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
                duration: Date.now() - start,
            };
        }
    }
    /**
     * Check error rate
     */
    async checkErrorRate() {
        const start = Date.now();
        try {
            const errorStats = error_handler_1.globalErrorHandler.getErrorStatistics();
            const last24hErrors = this.getErrorsLast24h();
            const errorRate = this.requestCount > 0 ? (this.failedRequests / this.requestCount) * 100 : 0;
            let status;
            let message;
            if (errorRate < 5) {
                status = 'pass';
                message = `Error rate normal (${errorRate.toFixed(1)}%)`;
            }
            else if (errorRate < 15) {
                status = 'warn';
                message = `Error rate elevated (${errorRate.toFixed(1)}%)`;
            }
            else {
                status = 'fail';
                message = `Error rate critical (${errorRate.toFixed(1)}%)`;
            }
            return {
                name: 'error_rate',
                status,
                message,
                duration: Date.now() - start,
                metadata: {
                    errorRate,
                    totalErrors: errorStats.totalErrors,
                    last24hErrors,
                },
            };
        }
        catch (error) {
            return {
                name: 'error_rate',
                status: 'fail',
                message: `Error rate check failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
                duration: Date.now() - start,
            };
        }
    }
    /**
     * Check performance metrics
     */
    async checkPerformance() {
        const start = Date.now();
        try {
            const avgResponseTime = this.getAverageResponseTime();
            const eventLoopDelay = this.measureEventLoopDelay();
            let status;
            let message;
            if (avgResponseTime < 1000 && eventLoopDelay < 10) {
                status = 'pass';
                message = `Performance normal (${avgResponseTime}ms avg response)`;
            }
            else if (avgResponseTime < 5000 && eventLoopDelay < 50) {
                status = 'warn';
                message = `Performance degraded (${avgResponseTime}ms avg response)`;
            }
            else {
                status = 'fail';
                message = `Performance critical (${avgResponseTime}ms avg response)`;
            }
            return {
                name: 'performance',
                status,
                message,
                duration: Date.now() - start,
                metadata: {
                    averageResponseTime: avgResponseTime,
                    eventLoopDelay,
                    uptime: Date.now() - this.startTime,
                },
            };
        }
        catch (error) {
            return {
                name: 'performance',
                status: 'fail',
                message: `Performance check failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
                duration: Date.now() - start,
            };
        }
    }
    /**
     * Check system dependencies
     */
    async checkDependencies() {
        const start = Date.now();
        try {
            // Test file system access
            const fs = await Promise.resolve().then(() => __importStar(require('fs')));
            const tmpDir = require('os').tmpdir();
            // Try to write a test file
            await fs.promises.writeFile(`${tmpDir}/datapilot-health-check`, 'test');
            await fs.promises.unlink(`${tmpDir}/datapilot-health-check`);
            return {
                name: 'dependencies',
                status: 'pass',
                message: 'All dependencies accessible',
                duration: Date.now() - start,
                metadata: {
                    fileSystem: 'accessible',
                    nodeVersion: process.version,
                },
            };
        }
        catch (error) {
            return {
                name: 'dependencies',
                status: 'fail',
                message: `Dependency check failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
                duration: Date.now() - start,
            };
        }
    }
    /**
     * Simple readiness check
     */
    isReady() {
        const memoryUsage = memory_manager_1.globalMemoryManager.getMemoryStats();
        const percentUsed = Math.round((memoryUsage.current.heapUsed / memoryUsage.current.heapTotal) * 100);
        return percentUsed < 90;
    }
    /**
     * Simple liveness check
     */
    isAlive() {
        return true; // If this code is running, the process is alive
    }
    getErrorsLast24h() {
        // This would require timestamp tracking in error handler
        // For now, return approximate based on total errors
        const errorStats = error_handler_1.globalErrorHandler.getErrorStatistics();
        return Math.floor(errorStats.totalErrors * 0.1); // Rough estimate
    }
    getAverageResponseTime() {
        if (this.responseTimes.length === 0)
            return 0;
        const sum = this.responseTimes.reduce((a, b) => a + b, 0);
        return Math.round(sum / this.responseTimes.length);
    }
    measureEventLoopDelay() {
        // Simple event loop delay measurement
        const start = process.hrtime.bigint();
        setImmediate(() => {
            const delta = process.hrtime.bigint() - start;
            return Number(delta / BigInt(1000000)); // Convert to milliseconds
        });
        return 0; // Placeholder - would need async implementation
    }
}
// Global health checker instance
exports.globalHealthChecker = new HealthChecker();
// Health check endpoints for production monitoring
exports.healthEndpoints = {
    '/health': () => exports.globalHealthChecker.checkHealth(),
    '/health/ready': () => ({ ready: exports.globalHealthChecker.isReady() }),
    '/health/live': () => ({ alive: exports.globalHealthChecker.isAlive() }),
    '/metrics': () => exports.globalHealthChecker.getMetrics(),
};
//# sourceMappingURL=health-checker.js.map