/**
 * Log Sampling Module
 *
 * Smart per-level sampling to reduce log volume and costs in production.
 * Critical logs (error, fatal, security) are always shipped.
 * Info and debug logs can be sampled based on configurable rates.
 *
 * Cost impact: Can reduce logging costs by 80%+ while preserving
 * all critical information for debugging.
 */

import type { StructuredLog } from './logger';

/** Log levels that are always shipped — never sampled */
const ALWAYS_SHIP_LEVELS = new Set(['error', 'fatal', 'security', 'warn']);

/** Default sample rates per level (1.0 = 100%, 0.1 = 10%) */
const DEFAULT_SAMPLE_RATES: Record<string, number> = {
  error: 1.0,
  fatal: 1.0,
  security: 1.0,
  warn: 1.0,
  info: 0.5,   // 50% in production
  debug: 0.1,  // 10% in production
  trace: 0.05, // 5% in production
};

/**
 * Get the configured sample rate for a given log level.
 * Environment variables override defaults:
 * - LOG_SAMPLE_RATE_INFO (default: 0.5)
 * - LOG_SAMPLE_RATE_DEBUG (default: 0.1)
 * - LOG_SAMPLE_RATE_TRACE (default: 0.05)
 *
 * In development, all logs are shipped (rate = 1.0).
 */
export function getSampleRate(level: string): number {
  if (process.env.NODE_ENV !== 'production') {
    return 1.0;
  }

  if (ALWAYS_SHIP_LEVELS.has(level)) {
    return 1.0;
  }

  const envKey = `LOG_SAMPLE_RATE_${level.toUpperCase()}`;
  const envValue = process.env[envKey];

  if (envValue !== undefined) {
    const parsed = parseFloat(envValue);
    if (!isNaN(parsed) && parsed >= 0 && parsed <= 1) {
      return parsed;
    }
  }

  return DEFAULT_SAMPLE_RATES[level] ?? 1.0;
}

/**
 * Decide whether a log entry should be shipped to external drains.
 * Uses deterministic sampling based on the configured rate.
 */
export function shouldShipLog(log: StructuredLog): boolean {
  const rate = getSampleRate(log.level);

  if (rate >= 1.0) return true;
  if (rate <= 0) return false;

  return Math.random() < rate;
}

/**
 * Get current sampling configuration for observability/debugging.
 * Useful for the staff dashboard to show what's being sampled.
 */
export function getSamplingConfig(): Record<string, { rate: number; description: string }> {
  const isProduction = process.env.NODE_ENV === 'production';

  const levels = ['trace', 'debug', 'info', 'warn', 'error', 'fatal', 'security'];

  return Object.fromEntries(
    levels.map((level) => {
      const rate = isProduction ? getSampleRate(level) : 1.0;
      const percentage = Math.round(rate * 100);
      const alwaysShip = ALWAYS_SHIP_LEVELS.has(level);

      return [
        level,
        {
          rate,
          description: alwaysShip
            ? `Always shipped (${percentage}%)`
            : isProduction
              ? `Sampled at ${percentage}% in production`
              : `All shipped in development (100%)`,
        },
      ];
    })
  );
}
