import test from 'node:test'
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

import { ENV_OVERRIDES } from './env-overrides.js'

const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url))
const BACKEND_ROOT = path.resolve(CURRENT_DIR, '../..')
const WORKSPACE_ROOT = process.env.WORKSPACE_ROOT || path.resolve(BACKEND_ROOT, '../..')

const SPECIAL_RUNTIME_ENV_NAMES = ['APP_BASE_URL', 'CLAIM_BASE_URL']

const DEPLOYMENT_ONLY_ENV_NAMES = [
  'APP_DOMAIN',
  'BACKEND_PORT',
  'CADDY_SITE_ADDR',
  'CHOKIDAR_USEPOLLING',
  'DB_BACKUP_KEEP',
  'DB_BACKUP_OSS_PREFIX',
  'KUASHOU_INDUSTRY_RATE_LIMIT_MAX',
  'MINIO_API_PORT',
  'MINIO_CONSOLE_PORT',
  'MINIO_ROOT_PASSWORD',
  'MINIO_ROOT_USER',
  'NPM_CONFIG_REGISTRY',
  'POSTGRES_DB',
  'POSTGRES_LOG_MIN_DURATION_STATEMENT_MS',
  'POSTGRES_MEM_LIMIT',
  'POSTGRES_CPUS',
  'POSTGRES_SHARED_BUFFERS',
  'POSTGRES_EFFECTIVE_CACHE_SIZE',
  'POSTGRES_WORK_MEM',
  'POSTGRES_MAINTENANCE_WORK_MEM',
  'BACKEND_MEM_LIMIT',
  'BACKEND_CPUS',
  'WEB_MEM_LIMIT',
  'WEB_CPUS',
  'POSTGRES_PASSWORD',
  'POSTGRES_PORT',
  'POSTGRES_USER',
  'TZ',
  'VITE_API_TARGET',
  'VITE_ALLOWED_HOSTS',
  'VITE_WORKER_SITE_URL',
  'WORKSPACE_ROOT',
  'WORKER_SITE_ADDR',
]

const KNOWN_ENV_NAMES = new Set([
  ...ENV_OVERRIDES.map((override) => override.env),
  ...SPECIAL_RUNTIME_ENV_NAMES,
  ...DEPLOYMENT_ONLY_ENV_NAMES,
])

test('env example files only document known runtime or deployment variables', () => {
  const envFiles = [
    path.join(WORKSPACE_ROOT, '.env.server.example'),
    path.join(WORKSPACE_ROOT, '.env.mac-docker.example'),
  ]

  const unknownNames = envFiles.flatMap((filePath) => {
    return extractExampleEnvNames(filePath)
      .filter((name) => !KNOWN_ENV_NAMES.has(name))
      .map((name) => `${path.basename(filePath)}:${name}`)
  })

  assert.deepEqual(unknownNames, [])
})

test('compose environment keys only use known runtime or deployment variables', () => {
  const composeFiles = [
    path.join(WORKSPACE_ROOT, 'docker-compose.yml'),
    path.join(WORKSPACE_ROOT, 'docker-compose.dev.yml'),
  ]

  const unknownNames = composeFiles.flatMap((filePath) => {
    return extractComposeEnvironmentKeys(filePath)
      .filter((name) => !KNOWN_ENV_NAMES.has(name))
      .map((name) => `${path.basename(filePath)}:${name}`)
  })

  assert.deepEqual(unknownNames, [])
})

function extractExampleEnvNames(filePath: string): string[] {
  const text = fs.readFileSync(filePath, 'utf8')
  return [...text.matchAll(/^([A-Z][A-Z0-9_]*)=/gm)].map((match) => match[1])
}

function extractComposeEnvironmentKeys(filePath: string): string[] {
  const text = fs.readFileSync(filePath, 'utf8')
  return [...text.matchAll(/^\s{6}([A-Z][A-Z0-9_]*):/gm)].map((match) => match[1])
}
