"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrometheusExporter = void 0;
/**
 * Convert internal metrics to Prometheus format
 */
class PrometheusExporter {
    constructor(prefix = 'somon_script') {
        this.prefix = prefix;
    }
    /**
     * Export metrics in Prometheus text format
     */
    exportMetrics(stats, circuitBreakers, additionalMetrics) {
        const lines = [];
        const timestamp = Date.now();
        if (stats) {
            this.addStatsMetrics(lines, stats, timestamp);
        }
        if (circuitBreakers) {
            this.addCircuitBreakerMetrics(lines, circuitBreakers, timestamp);
        }
        if (additionalMetrics) {
            this.addAdditionalMetrics(lines, additionalMetrics, timestamp);
        }
        // Add final newline
        lines.push('');
        return lines.join('\n');
    }
    /**
     * Add module system statistics metrics
     */
    addStatsMetrics(lines, stats, timestamp) {
        // System info
        lines.push(`# HELP ${this.prefix}_info System information`);
        lines.push(`# TYPE ${this.prefix}_info gauge`);
        lines.push(`${this.prefix}_info{node_version="${process.version}"} 1 ${timestamp}`);
        // Uptime
        lines.push(`# HELP ${this.prefix}_uptime_seconds System uptime in seconds`);
        lines.push(`# TYPE ${this.prefix}_uptime_seconds counter`);
        lines.push(`${this.prefix}_uptime_seconds ${stats.uptime.toFixed(2)} ${timestamp}`);
        // Module metrics
        lines.push(`# HELP ${this.prefix}_modules_loaded Total number of loaded modules`);
        lines.push(`# TYPE ${this.prefix}_modules_loaded gauge`);
        lines.push(`${this.prefix}_modules_loaded ${stats.modulesLoaded} ${timestamp}`);
        lines.push(`# HELP ${this.prefix}_modules_cached Number of cached modules`);
        lines.push(`# TYPE ${this.prefix}_modules_cached gauge`);
        lines.push(`${this.prefix}_modules_cached ${stats.modulesInCache} ${timestamp}`);
        lines.push(`# HELP ${this.prefix}_cache_hit_rate Cache hit rate`);
        lines.push(`# TYPE ${this.prefix}_cache_hit_rate gauge`);
        lines.push(`${this.prefix}_cache_hit_rate ${stats.cacheHitRate} ${timestamp}`);
        // Compilation latency metrics
        lines.push(`# HELP ${this.prefix}_compile_latency_avg_ms Average compilation time in milliseconds`);
        lines.push(`# TYPE ${this.prefix}_compile_latency_avg_ms gauge`);
        lines.push(`${this.prefix}_compile_latency_avg_ms ${stats.compileLatency.avg} ${timestamp}`);
        lines.push(`# HELP ${this.prefix}_compile_latency_p99_ms 99th percentile compilation time`);
        lines.push(`# TYPE ${this.prefix}_compile_latency_p99_ms gauge`);
        lines.push(`${this.prefix}_compile_latency_p99_ms ${stats.compileLatency.p99} ${timestamp}`);
        // Error metrics
        lines.push(`# HELP ${this.prefix}_load_errors_total Total load errors`);
        lines.push(`# TYPE ${this.prefix}_load_errors_total counter`);
        lines.push(`${this.prefix}_load_errors_total ${stats.loadErrors} ${timestamp}`);
        lines.push(`# HELP ${this.prefix}_compile_errors_total Total compilation errors`);
        lines.push(`# TYPE ${this.prefix}_compile_errors_total counter`);
        lines.push(`${this.prefix}_compile_errors_total ${stats.compileErrors} ${timestamp}`);
        lines.push(`# HELP ${this.prefix}_bundle_errors_total Total bundle errors`);
        lines.push(`# TYPE ${this.prefix}_bundle_errors_total counter`);
        lines.push(`${this.prefix}_bundle_errors_total ${stats.bundleErrors} ${timestamp}`);
        // Memory metrics
        lines.push(`# HELP ${this.prefix}_memory_rss_bytes Resident set size`);
        lines.push(`# TYPE ${this.prefix}_memory_rss_bytes gauge`);
        lines.push(`${this.prefix}_memory_rss_bytes ${stats.processMemoryUsage.rss} ${timestamp}`);
        lines.push(`# HELP ${this.prefix}_memory_heap_used_bytes Heap used`);
        lines.push(`# TYPE ${this.prefix}_memory_heap_used_bytes gauge`);
        lines.push(`${this.prefix}_memory_heap_used_bytes ${stats.processMemoryUsage.heapUsed} ${timestamp}`);
        lines.push(`# HELP ${this.prefix}_memory_heap_total_bytes Heap total`);
        lines.push(`# TYPE ${this.prefix}_memory_heap_total_bytes gauge`);
        lines.push(`${this.prefix}_memory_heap_total_bytes ${stats.processMemoryUsage.heapTotal} ${timestamp}`);
        // CPU metrics
        lines.push(`# HELP ${this.prefix}_cpu_usage_percent CPU usage percentage`);
        lines.push(`# TYPE ${this.prefix}_cpu_usage_percent gauge`);
        lines.push(`${this.prefix}_cpu_usage_percent ${stats.cpuUsage} ${timestamp}`);
        // Circuit breaker trips
        lines.push(`# HELP ${this.prefix}_circuit_breaker_trips_total Total circuit breaker trips`);
        lines.push(`# TYPE ${this.prefix}_circuit_breaker_trips_total counter`);
        lines.push(`${this.prefix}_circuit_breaker_trips_total ${stats.circuitBreakerTrips} ${timestamp}`);
    }
    /**
     * Helper to add metric header (HELP and TYPE lines)
     */
    addMetricHeader(lines, name, help, type) {
        const metricName = `${this.prefix}_${name}`;
        lines.push(`# HELP ${metricName} ${help}`, `# TYPE ${metricName} ${type}`);
    }
    /**
     * Helper to add a gauge metric
     */
    addGaugeMetric(lines, name, help, value, timestamp, labels = '') {
        this.addMetricHeader(lines, name, help, 'gauge');
        lines.push(`${this.prefix}_${name}${labels} ${value} ${timestamp}`);
    }
    /**
     * Add circuit breaker metrics
     */
    addCircuitBreakerMetrics(lines, circuitBreakers, timestamp) {
        const cbStats = circuitBreakers.getAllStatus();
        const overallHealth = circuitBreakers.getOverallHealth();
        this.addGaugeMetric(lines, 'circuit_breakers_total', 'Total number of circuit breakers', overallHealth.totalBreakers, timestamp);
        this.addGaugeMetric(lines, 'circuit_breakers_open', 'Number of open circuit breakers', overallHealth.openBreakers, timestamp);
        this.addGaugeMetric(lines, 'circuit_breakers_healthy', 'Number of healthy circuit breakers', overallHealth.healthyBreakers, timestamp);
        // Individual circuit breaker metrics
        this.addMetricHeader(lines, 'circuit_breaker_state', 'Circuit breaker state (0=closed, 1=open, 2=half-open)', 'gauge');
        this.addMetricHeader(lines, 'circuit_breaker_failures', 'Circuit breaker failure count', 'counter');
        this.addMetricHeader(lines, 'circuit_breaker_failure_rate', 'Circuit breaker failure rate', 'gauge');
        for (const [name, status] of Object.entries(cbStats)) {
            const stateValue = status.state === 'closed' ? 0 : status.state === 'open' ? 1 : 2;
            lines.push(`${this.prefix}_circuit_breaker_state{name="${name}"} ${stateValue} ${timestamp}`);
            lines.push(`${this.prefix}_circuit_breaker_failures{name="${name}"} ${status.failures} ${timestamp}`);
            lines.push(`${this.prefix}_circuit_breaker_failure_rate{name="${name}"} ${status.failureRate} ${timestamp}`);
        }
    }
    /**
     * Add additional custom metrics
     */
    addAdditionalMetrics(lines, additionalMetrics, timestamp) {
        for (const metric of additionalMetrics) {
            lines.push(`# HELP ${this.prefix}_${metric.name} ${metric.help}`);
            lines.push(`# TYPE ${this.prefix}_${metric.name} ${metric.type}`);
            const labels = metric.labels
                ? '{' +
                    Object.entries(metric.labels)
                        .map(([k, v]) => `${k}="${v}"`)
                        .join(',') +
                    '}'
                : '';
            lines.push(`${this.prefix}_${metric.name}${labels} ${metric.value} ${timestamp}`);
        }
    }
    /**
     * Create histogram buckets for response times
     */
    createResponseTimeHistogram(times, name = 'response_time') {
        const buckets = [10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000];
        const lines = [];
        const timestamp = Date.now();
        lines.push(`# HELP ${this.prefix}_${name}_ms Response time in milliseconds`);
        lines.push(`# TYPE ${this.prefix}_${name}_ms histogram`);
        for (const bucket of buckets) {
            const count = times.filter(t => t <= bucket).length;
            lines.push(`${this.prefix}_${name}_ms_bucket{le="${bucket}"} ${count} ${timestamp}`);
        }
        lines.push(`${this.prefix}_${name}_ms_bucket{le="+Inf"} ${times.length} ${timestamp}`);
        const sum = times.reduce((a, b) => a + b, 0);
        lines.push(`${this.prefix}_${name}_ms_sum ${sum} ${timestamp}`);
        lines.push(`${this.prefix}_${name}_ms_count ${times.length} ${timestamp}`);
        return lines;
    }
}
exports.PrometheusExporter = PrometheusExporter;
//# sourceMappingURL=prometheus-metrics.js.map