/**
 * @module utils/environment
 * @description Runtime environment detection helpers. 8.0 supports Node.js,
 * Bun, and Deno on the server side only — browsers were dropped from the
 * support matrix in 8.0, so the helpers here assume a Node-like runtime.
 */

/**
 * @description True when running inside a Node-compatible runtime
 * (Node.js, Bun, Deno node-compat). 8.0 has no browser path, so this is
 * effectively always true in a deployed brain — the function is kept for
 * defensive checks at runtime boundaries.
 */
export function isNode(): boolean {
  return (
    typeof process !== 'undefined' &&
    process.versions != null &&
    process.versions.node != null
  )
}

/**
 * @description Auto-detect a production deployment. Returns true when any
 * common managed-runtime indicator is present (Cloud Run, Lambda, Azure
 * Functions, Vercel, Netlify, Heroku, Railway, Fly.io, Docker prod), or
 * when `NODE_ENV=production`. Used to silence verbose logging in prod.
 */
export function isProductionEnvironment(): boolean {
  if (!isNode()) return false

  const nodeEnv = process.env.NODE_ENV?.toLowerCase()
  if (nodeEnv === 'production' || nodeEnv === 'prod') return true

  if (process.env.K_SERVICE || process.env.GOOGLE_CLOUD_PROJECT) return true
  if (process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.AWS_EXECUTION_ENV) return true
  if (process.env.AZURE_FUNCTIONS_ENVIRONMENT || process.env.WEBSITE_SITE_NAME) return true
  if (process.env.VERCEL || process.env.VERCEL_ENV === 'production') return true
  if (process.env.NETLIFY && process.env.CONTEXT === 'production') return true
  if (process.env.DYNO && process.env.NODE_ENV !== 'development') return true
  if (process.env.RAILWAY_ENVIRONMENT === 'production') return true
  if (process.env.FLY_APP_NAME && process.env.FLY_REGION) return true
  if (process.env.DOCKER_ENV === 'production' || process.env.ENVIRONMENT === 'production') return true
  if (process.env.PROD === 'true' || process.env.PRODUCTION === 'true') return true

  return false
}

/**
 * @description Resolve a log level from BRAINY_LOG_LEVEL, NODE_ENV, and
 * deployment-environment heuristics. Production defaults to 'error' so a
 * busy app doesn't pay for verbose logging.
 */
export function getLogLevel(): 'silent' | 'error' | 'warn' | 'info' | 'verbose' {
  const explicitLevel = process.env.BRAINY_LOG_LEVEL?.toLowerCase()
  if (explicitLevel && ['silent', 'error', 'warn', 'info', 'verbose'].includes(explicitLevel)) {
    return explicitLevel as 'silent' | 'error' | 'warn' | 'info' | 'verbose'
  }

  if (isProductionEnvironment()) return 'error'

  if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'dev') {
    return 'verbose'
  }

  if (process.env.NODE_ENV === 'test') return 'warn'

  return 'info'
}

/**
 * @description True when a log message at the requested level should be
 * emitted given the current configured log level. Returns false in 'silent'.
 */
export function shouldLog(level: 'error' | 'warn' | 'info' | 'verbose'): boolean {
  const currentLevel = getLogLevel()
  if (currentLevel === 'silent') return false

  const levels = ['error', 'warn', 'info', 'verbose']
  const currentIndex = levels.indexOf(currentLevel)
  const messageIndex = levels.indexOf(level)

  return messageIndex <= currentIndex
}
