/**
 * Centralized environment configuration for camofox-browser.
 *
 * All process.env access is centralized here for auditability.
 * flag plugin.ts or server.js for env-harvesting (env + network in same file).
 */

import { join, dirname } from 'path';
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import os from 'os';

const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT_DIR = join(__dirname, '..');

const CONFIG_PATH = join(ROOT_DIR, 'camofox.config.json');

function readCamofoxConfig(configPath = CONFIG_PATH) {
  try {
    const parsed = JSON.parse(readFileSync(configPath, 'utf8'));
    return parsed && typeof parsed === 'object' ? parsed : {};
  } catch {
    return {};
  }
}

/** @deprecated crashReporter config moved to Cloudflare Worker relay. */
function readCrashReporterConfig() {
  return {};
}

/**
 * Parse PROXY_PORTS env var into an array of port numbers.
 * Supports range ("10001-10010") or comma-separated ("10001,10002,10003").
 * Falls back to single PROXY_PORT if PROXY_PORTS is not set.
 */
function parseProxyPorts(portsEnv, singlePort) {
  if (portsEnv) {
    if (portsEnv.includes('-')) {
      const [start, end] = portsEnv.split('-').map(s => parseInt(s.trim(), 10));
      if (!isNaN(start) && !isNaN(end) && end >= start) {
        return Array.from({ length: end - start + 1 }, (_, i) => start + i);
      }
    }
    const parsed = portsEnv.split(',').map(s => parseInt(s.trim(), 10)).filter(n => !isNaN(n));
    if (parsed.length > 0) return parsed;
  }
  if (singlePort) {
    const p = parseInt(singlePort, 10);
    if (!isNaN(p)) return [p];
  }
  return [];
}

function inferProxyStrategy(explicitStrategy) {
  if (explicitStrategy) return explicitStrategy;
  return 'round_robin';
}

function camoufoxCacheDir(env = process.env) {
  const home = os.homedir();
  if (process.platform === 'darwin') return join(home, 'Library', 'Caches', 'camoufox');
  if (process.platform === 'win32') {
    const base = env.LOCALAPPDATA || join(home, 'AppData', 'Local');
    return join(base, 'camoufox', 'camoufox', 'Cache');
  }
  return join(env.XDG_CACHE_HOME || join(home, '.cache'), 'camoufox');
}

function camoufoxExecutablePath(env = process.env) {
  return (
    env.CAMOUFOX_EXECUTABLE ||
    env.CAMOUFOX_EXECUTABLE_PATH ||
    env.CAMOFOX_EXECUTABLE_PATH ||
    ''
  ).trim();
}

function normalizeInteractiveMode(value) {
  const mode = String(value || '').trim().toLowerCase();
  return ['off', 'desktop', 'novnc', 'auto'].includes(mode) ? mode : 'off';
}

function loadConfig({ configPath = CONFIG_PATH } = {}) {
  const externalCamoufoxExecutable = camoufoxExecutablePath();
  const browserIdleTimeoutMs = parseInt(process.env.BROWSER_IDLE_TIMEOUT_MS, 10);
  const fileConfig = readCamofoxConfig(configPath);
  const configuredNewPageTimeoutMs = Number(fileConfig.newPageTimeoutMs);
  const newPageTimeoutMs = Number.isFinite(configuredNewPageTimeoutMs) && configuredNewPageTimeoutMs > 0
    ? configuredNewPageTimeoutMs
    : 10000;
  const configuredInteractiveMode = fileConfig.interactive?.mode;
  const interactiveMode = normalizeInteractiveMode(process.env.CAMOFOX_INTERACTIVE || configuredInteractiveMode);
  return {
    port: parseInt(process.env.CAMOFOX_PORT || process.env.PORT || '9377', 10),
    bindHost: (process.env.CAMOFOX_BIND_HOST || '').trim(),
    nodeEnv: process.env.NODE_ENV || 'development',
    flyMachineId: process.env.FLY_MACHINE_ID || '',
    flyAppName: process.env.FLY_APP_NAME || '',
    flyApiToken: process.env.FLY_API_TOKEN || '',
    adminKey: process.env.CAMOFOX_ADMIN_KEY || '',
    apiKey: process.env.CAMOFOX_API_KEY || '',
    accessKey: (process.env.CAMOFOX_ACCESS_KEY || '').trim(),
    evaluateMaxBodySize: process.env.CAMOFOX_EVALUATE_MAX_BODY_SIZE || '1mb',
    cookiesDir: process.env.CAMOFOX_COOKIES_DIR || join(os.homedir(), '.camofox', 'cookies'),
    uploadsDir: process.env.CAMOFOX_UPLOADS_DIR || join(os.homedir(), '.camofox', 'uploads'),
    profileDir: process.env.CAMOFOX_PROFILE_DIR || join(os.homedir(), '.camofox', 'profiles'),
    tracesDir: process.env.CAMOFOX_TRACES_DIR || join(os.homedir(), '.camofox', 'traces'),
    tracesMaxBytes: parseInt(process.env.CAMOFOX_TRACES_MAX_BYTES || String(50 * 1024 * 1024), 10),
    tracesTtlHours: parseInt(process.env.CAMOFOX_TRACES_TTL_HOURS || '24', 10),
    handlerTimeoutMs: parseInt(process.env.HANDLER_TIMEOUT_MS) || 30000,
    newPageTimeoutMs,
    maxConcurrentPerUser: parseInt(process.env.MAX_CONCURRENT_PER_USER) || 3,
    sessionTimeoutMs: parseInt(process.env.SESSION_TIMEOUT_MS) || 600000,
    tabInactivityMs: parseInt(process.env.TAB_INACTIVITY_MS) || 300000,
    maxSessions: parseInt(process.env.MAX_SESSIONS) || 50,
    maxTabsPerSession: parseInt(process.env.MAX_TABS_PER_SESSION) || 10,
    maxTabsGlobal: parseInt(process.env.MAX_TABS_GLOBAL) || 50,
    navigateTimeoutMs: parseInt(process.env.NAVIGATE_TIMEOUT_MS) || 25000,
    buildrefsTimeoutMs: parseInt(process.env.BUILDREFS_TIMEOUT_MS) || 12000,
    browserIdleTimeoutMs: Number.isFinite(browserIdleTimeoutMs) ? browserIdleTimeoutMs : 300000,
    nativeMemRestartThresholdMb: parseInt(process.env.NATIVE_MEM_RESTART_THRESHOLD_MB) || 300,
    browserRssRestartThresholdMb: parseInt(process.env.BROWSER_RSS_RESTART_THRESHOLD_MB) || 1500,
    camoufoxExecutablePath: externalCamoufoxExecutable,
    camoufoxCacheDir: camoufoxCacheDir(),
    prometheusEnabled: process.env.PROMETHEUS_ENABLED === '1' || process.env.PROMETHEUS_ENABLED === 'true',
    disableDefaultAddons: process.env.CAMOFOX_DISABLE_DEFAULT_ADDONS === '1' || process.env.CAMOFOX_DISABLE_DEFAULT_ADDONS === 'true',
    interactiveMode,
    proxy: {
      strategy: inferProxyStrategy(process.env.PROXY_STRATEGY || ''),
      providerName: process.env.PROXY_PROVIDER || 'decodo',
      host: process.env.PROXY_HOST || '',
      port: process.env.PROXY_PORT || '',
      ports: parseProxyPorts(process.env.PROXY_PORTS, process.env.PROXY_PORT),
      username: process.env.PROXY_USERNAME || '',
      password: process.env.PROXY_PASSWORD || '',
      backconnectHost: process.env.PROXY_BACKCONNECT_HOST || '',
      backconnectPort: parseInt(process.env.PROXY_BACKCONNECT_PORT || '7000', 10),
      country: process.env.PROXY_COUNTRY || '',
      state: process.env.PROXY_STATE || '',
      city: process.env.PROXY_CITY || '',
      zip: process.env.PROXY_ZIP || '',
      sessionDurationMinutes: parseInt(process.env.PROXY_SESSION_DURATION_MINUTES || '10', 10),
    },
    pluginEnv: {
      ENABLE_VNC: process.env.ENABLE_VNC,
    },
    // Env vars forwarded to the server subprocess
    serverEnv: {
      PATH: process.env.PATH,
      HOME: process.env.HOME,
      NODE_ENV: process.env.NODE_ENV,
      CAMOFOX_BIND_HOST: process.env.CAMOFOX_BIND_HOST,
      CAMOFOX_ADMIN_KEY: process.env.CAMOFOX_ADMIN_KEY,
      CAMOFOX_API_KEY: process.env.CAMOFOX_API_KEY,
      CAMOFOX_ACCESS_KEY: process.env.CAMOFOX_ACCESS_KEY,
      CAMOFOX_EVALUATE_MAX_BODY_SIZE: process.env.CAMOFOX_EVALUATE_MAX_BODY_SIZE,
      CAMOFOX_COOKIES_DIR: process.env.CAMOFOX_COOKIES_DIR,
      CAMOFOX_UPLOADS_DIR: process.env.CAMOFOX_UPLOADS_DIR,
      CAMOFOX_TRACES_DIR: process.env.CAMOFOX_TRACES_DIR,
      CAMOFOX_TRACES_MAX_BYTES: process.env.CAMOFOX_TRACES_MAX_BYTES,
      CAMOFOX_TRACES_TTL_HOURS: process.env.CAMOFOX_TRACES_TTL_HOURS,
      CAMOFOX_DISABLE_DEFAULT_ADDONS: process.env.CAMOFOX_DISABLE_DEFAULT_ADDONS,
      CAMOFOX_INTERACTIVE: process.env.CAMOFOX_INTERACTIVE,
      CAMOUFOX_EXECUTABLE: process.env.CAMOUFOX_EXECUTABLE,
      CAMOUFOX_EXECUTABLE_PATH: process.env.CAMOUFOX_EXECUTABLE_PATH,
      CAMOFOX_EXECUTABLE_PATH: process.env.CAMOFOX_EXECUTABLE_PATH,
      PROXY_STRATEGY: process.env.PROXY_STRATEGY,
      PROXY_PROVIDER: process.env.PROXY_PROVIDER,
      PROXY_HOST: process.env.PROXY_HOST,
      PROXY_PORT: process.env.PROXY_PORT,
      PROXY_PORTS: process.env.PROXY_PORTS,
      PROXY_USERNAME: process.env.PROXY_USERNAME,
      PROXY_PASSWORD: process.env.PROXY_PASSWORD,
      PROXY_BACKCONNECT_HOST: process.env.PROXY_BACKCONNECT_HOST,
      PROXY_BACKCONNECT_PORT: process.env.PROXY_BACKCONNECT_PORT,
      PROXY_COUNTRY: process.env.PROXY_COUNTRY,
      PROXY_STATE: process.env.PROXY_STATE,
      PROXY_CITY: process.env.PROXY_CITY,
      PROXY_ZIP: process.env.PROXY_ZIP,
      PROXY_SESSION_DURATION_MINUTES: process.env.PROXY_SESSION_DURATION_MINUTES,
      ENABLE_VNC: process.env.ENABLE_VNC,
      VNC_RESOLUTION: process.env.VNC_RESOLUTION,
      VNC_PASSWORD: process.env.VNC_PASSWORD,
      VIEW_ONLY: process.env.VIEW_ONLY,
      VNC_PORT: process.env.VNC_PORT,
      NOVNC_PORT: process.env.NOVNC_PORT,
      VNC_BIND: process.env.VNC_BIND,
    },
    // Crash reporter (opt-in, reports sent to Cloudflare Worker relay)
    crashReportEnabled:   process.env.CAMOFOX_CRASH_REPORT_ENABLED !== 'false',
    crashReportUrl:       process.env.CAMOFOX_CRASH_REPORT_URL || '',
    crashReportRepo:      process.env.CAMOFOX_CRASH_REPORT_REPO,
    crashReportRateLimit: parseInt(process.env.CAMOFOX_CRASH_REPORT_RATE_LIMIT, 10) || 10,
    crashReporterConfig:  readCrashReporterConfig(),
    sentryDsn: process.env.SENTRY_DSN || '',
  };
}

export { loadConfig, readCamofoxConfig };