/**
 * Log capture middleware for monitoring log buffer (Portal `/api/monitoring/logs`).
 * Intercepts logger calls and feeds them to the monitoring ring buffer.
 *
 * Skips `memoryLogger` (no `getCorrelationId`; uses its own `getLogs()` buffer).
 */

import { addMonitoringLog } from '../routes/monitoring.js';

const MONITORING_WRAPPED = '__monitoringWrapped';

/**
 * Wrap a logger to capture log entries for monitoring.
 * Idempotent: already-wrapped loggers are returned unchanged.
 */
export function wrapLoggerForMonitoring(logger: any): any {
  if (!logger || typeof logger.info !== 'function') {
    return logger;
  }
  if (logger[MONITORING_WRAPPED]) {
    return logger;
  }
  // memoryLogger: separate in-memory buffer for no-persistence mode — do not duplicate
  if (typeof logger.getLogs === 'function') {
    return logger;
  }

  const originalInfo = logger.info.bind(logger);
  const originalWarn = logger.warn.bind(logger);
  const originalError = logger.error.bind(logger);
  const originalDebug = logger.debug?.bind(logger);

  const resolveCorrelationId = (
    data?: Record<string, unknown>
  ): string | undefined => {
    if (data && typeof data['correlationId'] === 'string') {
      return data['correlationId'];
    }
    if (typeof logger.getCorrelationId === 'function') {
      return logger.getCorrelationId();
    }
    return undefined;
  };

  const logContext =
    typeof logger.getComponent === 'function'
      ? logger.getComponent()
      : typeof logger.prefix === 'string'
        ? logger.prefix
        : 'Gateway';

  const capture = (
    level: 'info' | 'warn' | 'error' | 'debug',
    message: string,
    data?: Record<string, unknown>
  ) => {
    const correlationId = resolveCorrelationId(data);
    addMonitoringLog({
      timestamp: new Date().toISOString(),
      level,
      message,
      context: logContext,
      ...(correlationId && { correlationId }),
      ...(data && { data }),
    });
  };

  logger.info = (message: string, data?: Record<string, unknown>) => {
    capture('info', message, data);
    return originalInfo(message, data);
  };

  logger.warn = (message: string, data?: Record<string, unknown>) => {
    capture('warn', message, data);
    return originalWarn(message, data);
  };

  logger.error = (message: string, data?: Record<string, unknown>) => {
    capture('error', message, data);
    return originalError(message, data);
  };

  if (originalDebug) {
    logger.debug = (message: string, data?: Record<string, unknown>) => {
      capture('debug', message, data);
      return originalDebug(message, data);
    };
  }

  logger[MONITORING_WRAPPED] = true;
  return logger;
}
