// Prometheus Integration Service
// Metrics collection and export for IRU services

export interface Metric {
  name: string;
  value: number;
  labels?: Record<string, string>;
  timestamp?: Date;
}

export interface ServiceMetrics {
  serviceName: string;
  metrics: Metric[];
  timestamp: Date;
}

export class PrometheusIntegrationService {
  private prometheusPushGateway?: string;
  private prometheusJobName: string;

  constructor() {
    this.prometheusPushGateway = process.env.PROMETHEUS_PUSH_GATEWAY;
    this.prometheusJobName = process.env.PROMETHEUS_JOB_NAME || 'dbis-iru';
  }

  /**
   * Push metrics to Prometheus
   */
  async pushMetrics(metrics: ServiceMetrics): Promise<void> {
    if (!this.prometheusPushGateway) {
      // If no push gateway configured, metrics will be scraped instead
      return;
    }

    const prometheusFormat = this.formatPrometheusMetrics(metrics);

    const response = await fetch(`${this.prometheusPushGateway}/metrics/job/${this.prometheusJobName}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'text/plain',
      },
      body: prometheusFormat,
    });

    if (!response.ok) {
      throw new Error(`Prometheus push failed: ${response.status} ${response.statusText}`);
    }
  }

  /**
   * Format metrics in Prometheus format
   */
  private formatPrometheusMetrics(metrics: ServiceMetrics): string {
    const lines: string[] = [];

    for (const metric of metrics.behavioral_metrics) {
      const labels = metric.labels || {};
      labels.service = metrics.serviceName;

      const labelString = Object.entries(labels)
        .map(([key, value]) => `${key}="${value}"`)
        .join(',');

      const timestamp = metric.timestamp ? metric.timestamp.getTime() : Date.now();
      const value = metric.value;

      lines.push(`${metric.name}{${labelString}} ${value} ${timestamp}`);
    }

    return lines.join('\n') + '\n';
  }

  /**
   * Record IRU-specific metrics
   */
  async recordIRUMetrics(subscriptionId: string, metrics: {
    inquiryCount?: number;
    qualificationTime?: number;
    deploymentTime?: number;
    activeSubscriptions?: number;
    serviceUptime?: number;
    transactionCount?: number;
    errorRate?: number;
  }): Promise<void> {
    const prometheusMetrics: Metric[] = [];

    if (metrics.inquiryCount !== undefined) {
      prometheusMetrics.push({
        name: 'dbis_iru_inquiries_total',
        value: metrics.inquiryCount,
        labels: { subscription_id: subscriptionId },
      });
    }

    if (metrics.qualificationTime !== undefined) {
      prometheusMetrics.push({
        name: 'dbis_iru_qualification_duration_seconds',
        value: metrics.qualificationTime,
        labels: { subscription_id: subscriptionId },
      });
    }

    if (metrics.deploymentTime !== undefined) {
      prometheusMetrics.push({
        name: 'dbis_iru_deployment_duration_seconds',
        value: metrics.deploymentTime,
        labels: { subscription_id: subscriptionId },
      });
    }

    if (metrics.activeSubscriptions !== undefined) {
      prometheusMetrics.push({
        name: 'dbis_iru_active_subscriptions',
        value: metrics.activeSubscriptions,
      });
    }

    if (metrics.serviceUptime !== undefined) {
      prometheusMetrics.push({
        name: 'dbis_iru_service_uptime_percent',
        value: metrics.serviceUptime,
        labels: { subscription_id: subscriptionId },
      });
    }

    if (metrics.transactionCount !== undefined) {
      prometheusMetrics.push({
        name: 'dbis_iru_transactions_total',
        value: metrics.transactionCount,
        labels: { subscription_id: subscriptionId },
      });
    }

    if (metrics.errorRate !== undefined) {
      prometheusMetrics.push({
        name: 'dbis_iru_error_rate',
        value: metrics.errorRate,
        labels: { subscription_id: subscriptionId },
      });
    }

    await this.pushMetrics({
      serviceName: 'iru-service',
      metrics: prometheusMetrics,
      timestamp: new Date(),
    });
  }

  /**
   * Get metrics endpoint (for Prometheus scraping)
   */
  getMetricsEndpoint(): string {
    return '/metrics';
  }

  /**
   * Generate metrics response
   */
  generateMetricsResponse(metrics: ServiceMetrics[]): string {
    const allMetrics: Metric[] = [];
    for (const serviceMetrics of metrics) {
      allMetrics.push(...serviceMetrics.behavioral_metrics);
    }

    return this.formatPrometheusMetrics({
      serviceName: 'dbis-iru',
      metrics: allMetrics,
      timestamp: new Date(),
    });
  }
}

export const prometheusIntegrationService = new PrometheusIntegrationService();
