import express from 'express';
import { logger } from '../logger.js';
import { ConfigManager } from '../config-manager.js';
import { createWorkerRegistry } from '../metrics/registry.js';
import { createWorkerMetrics, type WorkerMetrics } from '../metrics/worker-metrics.js';
import { createMetricsHandler } from '../metrics/http-handler.js';

/**
 * Phase 3b: Prometheus /metrics endpoint, extracted verbatim from
 * createCoreServer (bridge/server.ts). Mounted BEFORE any auth middleware so
 * the standard Prometheus scrape job works without a session cookie.
 * Restrict scrape access at the reverse proxy / firewall layer (see help
 * doc). Disabled by provider.metrics.enabled=false in config.yaml.
 */
export function setupMetricsSubsystem(
  app: express.Application,
  configManager: ConfigManager | undefined,
): {
  workerMetrics: WorkerMetrics | null;
  /** Phase 3c: shared prom-client registry so the same-process gateway mount
   *  can register its gateway_* counters into the same /metrics endpoint
   *  (one scrape serves both worker and gateway). Null when metrics are
   *  disabled. */
  sharedPromRegistry: import('prom-client').Registry | null;
} {
  const appConfig = (() => {
    try { return configManager?.getConfig() ?? null; } catch { return null; }
  })();
  const metricsCfg = appConfig?.provider?.metrics;
  let workerMetrics: WorkerMetrics | null = null;
  let sharedPromRegistry: import('prom-client').Registry | null = null;
  if (metricsCfg?.enabled !== false) {
    const prefix = metricsCfg?.prefix ?? 'aao_worker';
    sharedPromRegistry = createWorkerRegistry(prefix);
    workerMetrics = createWorkerMetrics(sharedPromRegistry, prefix);
    // Phase 3b post-review: gate /metrics on (1) bearer token if set,
    // (2) otherwise client-IP allowlist (default localhost). Labels
    // like `worker_id` / `backend_id` would leak otherwise.
    const metricsAuth = {
      bearerToken: metricsCfg?.bearerToken,
      allowedHosts: metricsCfg?.allowedHosts,
    };
    app.get('/metrics', createMetricsHandler(sharedPromRegistry, metricsAuth));
    const authMode = metricsAuth.bearerToken
      ? 'bearer'
      : `ip-allowlist=${(metricsAuth.allowedHosts ?? ['127.0.0.1', '::1', 'localhost']).join(',')}`;
    logger.info(`[bridge] worker metrics enabled prefix=${prefix} auth=${authMode}`);
  } else {
    logger.info('[bridge] worker metrics disabled (provider.metrics.enabled=false)');
  }
  return { workerMetrics, sharedPromRegistry };
}
