'use strict';

/**
 * config.js — Centralized env-var config with validation.
 * All config is read from environment variables.
 * Throws on missing required variables at startup.
 */

function getEnv(name, defaultValue, required = false) {
  const val = process.env[name];
  if (val === undefined || val === '') {
    if (required) {
      throw new Error(`Required environment variable ${name} is not set`);
    }
    return defaultValue;
  }
  return val;
}

function getEnvInt(name, defaultValue, required = false) {
  const val = getEnv(name, undefined, required);
  if (val === undefined) return defaultValue;
  const n = parseInt(val, 10);
  if (isNaN(n)) throw new Error(`Environment variable ${name} must be an integer, got: ${val}`);
  return n;
}

function getEnvBool(name, defaultValue) {
  const val = process.env[name];
  if (val === undefined || val === '') return defaultValue;
  return val === '1' || val.toLowerCase() === 'true' || val.toLowerCase() === 'yes';
}

/**
 * Build and validate the config object.
 * Called once at startup; throws on invalid config.
 */
function buildConfig() {
  const config = {
    // Mattermost API
    mm: {
      token: getEnv('MM_BOT_TOKEN', null, true),
      baseUrl: getEnv('MM_BASE_URL', 'https://slack.solio.tech'),
      maxSockets: getEnvInt('MM_MAX_SOCKETS', 4),
    },

    // Transcript directory (OpenClaw agents)
    transcriptDir: getEnv('TRANSCRIPT_DIR', '/home/node/.openclaw/agents'),

    // Timing
    throttleMs: getEnvInt('THROTTLE_MS', 500),
    idleTimeoutS: getEnvInt('IDLE_TIMEOUT_S', 60),
    sessionPollMs: getEnvInt('SESSION_POLL_MS', 2000),

    // Limits
    maxActiveSessions: getEnvInt('MAX_ACTIVE_SESSIONS', 20),
    maxMessageChars: getEnvInt('MAX_MESSAGE_CHARS', 15000),
    maxStatusLines: getEnvInt('MAX_STATUS_LINES', 20),
    maxRetries: getEnvInt('MAX_RETRIES', 3),

    // Circuit breaker
    circuitBreakerThreshold: getEnvInt('CIRCUIT_BREAKER_THRESHOLD', 5),
    circuitBreakerCooldownS: getEnvInt('CIRCUIT_BREAKER_COOLDOWN_S', 30),

    // Health check
    healthPort: getEnvInt('HEALTH_PORT', 9090),

    // Logging
    logLevel: getEnv('LOG_LEVEL', 'info'),

    // PID file
    pidFile: getEnv('PID_FILE', '/tmp/status-watcher.pid'),

    // Offset persistence
    offsetFile: getEnv('OFFSET_FILE', '/tmp/status-watcher-offsets.json'),

    // Optional external tool labels override
    toolLabelsFile: getEnv('TOOL_LABELS_FILE', null),

    // Fallback channel for non-MM sessions (null = skip)
    defaultChannel: getEnv('DEFAULT_CHANNEL', null),

    // Feature flags
    enableFsWatch: getEnvBool('ENABLE_FS_WATCH', true),
  };

  // Validate MM base URL
  try {
    new URL(config.mm.baseUrl);
  } catch (_e) {
    throw new Error(`MM_BASE_URL is not a valid URL: ${config.mm.baseUrl}`);
  }

  return config;
}

// Singleton — built once, exported
let _config = null;

function getConfig() {
  if (!_config) {
    _config = buildConfig();
  }
  return _config;
}

// Allow resetting config in tests
function resetConfig() {
  _config = null;
}

module.exports = { getConfig, resetConfig, buildConfig };
