#!/usr/bin/env node

import { readFile } from "node:fs/promises";
import path from "node:path";

const targetPath = path.resolve(process.cwd(), process.argv[2] || ".env.production");

const requiredKeys = [
  "PUBLIC_DOMAIN",
  "PUBLIC_URL",
  "TLS_EMAIL",
  "BETTER_AUTH_SECRET",
  "MAIL_ENCRYPTION_KEY",
  "CORS_ALLOW_ORIGINS",
  "AUTH_MAGIC_LINK_PROVIDER",
  "AUTH_MAIL_FROM",
  "AUTH_SMTP_HOST",
  "AUTH_SMTP_PORT",
  "AUTH_SMTP_SECURE",
  "AUTH_SMTP_USER",
  "AUTH_SMTP_PASSWORD",
  "POSTGRES_PASSWORD",
  "S3_REGION",
  "S3_BUCKET",
  "S3_ACCESS_KEY",
  "S3_SECRET_KEY"
];

const secretKeys = [
  "BETTER_AUTH_SECRET",
  "MAIL_ENCRYPTION_KEY",
  "AUTH_SMTP_PASSWORD",
  "POSTGRES_PASSWORD",
  "S3_ACCESS_KEY",
  "S3_SECRET_KEY"
];

const optionalSecretKeys = [
  "METRICS_AUTH_TOKEN"
];

const insecureSecretValues = new Set([
  "",
  "changeme",
  "change-me",
  "replace-me",
  "replace-with-a-long-random-secret",
  "replace-with-a-different-long-random-secret",
  "replace-with-smtp-password",
  "replace-with-strong-password",
  "replace-with-access-key",
  "replace-with-secret-key",
  "replace-with-metrics-token"
]);

function stripOptionalQuotes(value) {
  const trimmed = value.trim();
  if ((trimmed.startsWith("\"") && trimmed.endsWith("\"")) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
    return trimmed.slice(1, -1);
  }
  return trimmed;
}

function parseEnv(raw) {
  const result = new Map();
  for (const line of raw.split(/\r?\n/)) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith("#")) {
      continue;
    }
    const normalized = trimmed.startsWith("export ") ? trimmed.slice("export ".length).trim() : trimmed;
    const equalsIndex = normalized.indexOf("=");
    if (equalsIndex <= 0) {
      continue;
    }
    const key = normalized.slice(0, equalsIndex).trim();
    const value = stripOptionalQuotes(normalized.slice(equalsIndex + 1));
    result.set(key, value);
  }
  return result;
}

function isLocalHost(hostname) {
  const normalized = String(hostname || "").toLowerCase();
  return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1";
}

function parseAbsoluteURL(value, envName, errors) {
  try {
    const parsed = new URL(value);
    if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
      errors.push(`${envName} must use http or https`);
      return null;
    }
    return parsed;
  } catch {
    errors.push(`${envName} must be a valid absolute URL`);
    return null;
  }
}

function isLikelyEmail(value) {
  const normalized = String(value || "").trim();
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(normalized);
}

function parseBoolean(value) {
  const normalized = String(value || "").trim().toLowerCase();
  if (normalized === "true" || normalized === "1" || normalized === "yes") {
    return true;
  }
  if (normalized === "false" || normalized === "0" || normalized === "no") {
    return false;
  }
  return null;
}

function normalizeOrigin(url) {
  return `${url.protocol}//${url.host}`.toLowerCase();
}

async function main() {
  const errors = [];
  const warnings = [];

  let raw;
  try {
    raw = await readFile(targetPath, "utf8");
  } catch (error) {
    console.error(`[error] failed to read ${targetPath}: ${error instanceof Error ? error.message : String(error)}`);
    process.exit(1);
  }

  const env = parseEnv(raw);

  for (const key of requiredKeys) {
    const value = env.get(key);
    if (!value || !value.trim()) {
      errors.push(`${key} is required`);
    }
  }

  for (const key of secretKeys) {
    const value = String(env.get(key) || "").trim();
    const normalized = value.toLowerCase();
    if (insecureSecretValues.has(normalized) || value.length < 16) {
      errors.push(`${key} must be a strong non-placeholder secret (minimum 16 characters)`);
    }
  }

  for (const key of optionalSecretKeys) {
    const value = String(env.get(key) || "").trim();
    if (!value) {
      continue;
    }
    const normalized = value.toLowerCase();
    if (insecureSecretValues.has(normalized) || value.length < 16) {
      errors.push(`${key} must be a strong non-placeholder secret (minimum 16 characters) when set`);
    }
  }

  const publicURL = env.get("PUBLIC_URL");
  const publicDomain = String(env.get("PUBLIC_DOMAIN") || "").trim().toLowerCase();
  let normalizedPublicOrigin = "";
  if (publicURL) {
    const parsedPublicURL = parseAbsoluteURL(publicURL, "PUBLIC_URL", errors);
    if (parsedPublicURL) {
      normalizedPublicOrigin = normalizeOrigin(parsedPublicURL);
      if (!isLocalHost(parsedPublicURL.hostname) && parsedPublicURL.protocol !== "https:") {
        errors.push("PUBLIC_URL must use https for non-local deployments");
      }
      if (publicDomain && parsedPublicURL.hostname.toLowerCase() !== publicDomain) {
        errors.push(`PUBLIC_URL host (${parsedPublicURL.hostname}) must match PUBLIC_DOMAIN (${publicDomain})`);
      }
    }
  }

  const corsOrigins = env.get("CORS_ALLOW_ORIGINS");
  if (corsOrigins) {
    if (corsOrigins.includes("*")) {
      errors.push("CORS_ALLOW_ORIGINS cannot include '*'");
    }
    const normalizedCorsOrigins = new Set();
    for (const rawOrigin of corsOrigins.split(",")) {
      const origin = rawOrigin.trim();
      if (!origin) {
        continue;
      }
      const parsedOrigin = parseAbsoluteURL(origin, "CORS_ALLOW_ORIGINS", errors);
      if (!parsedOrigin) {
        continue;
      }
      if ((parsedOrigin.pathname && parsedOrigin.pathname !== "/") || parsedOrigin.search || parsedOrigin.hash) {
        errors.push(`CORS_ALLOW_ORIGINS origin must not include path/query/fragment: ${origin}`);
      }
      if (!isLocalHost(parsedOrigin.hostname) && parsedOrigin.protocol !== "https:") {
        errors.push(`CORS_ALLOW_ORIGINS origin must use https for non-local deployments: ${origin}`);
      }
      if (publicDomain !== "localhost" && isLocalHost(parsedOrigin.hostname)) {
        errors.push(`CORS_ALLOW_ORIGINS cannot include localhost in production: ${origin}`);
      }
      normalizedCorsOrigins.add(normalizeOrigin(parsedOrigin));
    }

    if (normalizedPublicOrigin && !normalizedCorsOrigins.has(normalizedPublicOrigin)) {
      errors.push(`CORS_ALLOW_ORIGINS must include PUBLIC_URL origin (${normalizedPublicOrigin})`);
    }
  }

  const magicLinkProvider = String(env.get("AUTH_MAGIC_LINK_PROVIDER") || "").trim().toLowerCase();
  if (magicLinkProvider !== "smtp") {
    errors.push("AUTH_MAGIC_LINK_PROVIDER must be smtp for production deployments");
  }

  const authDevMailboxEnabled = String(env.get("AUTH_DEV_MAILBOX_ENABLED") || "").trim().toLowerCase();
  if (authDevMailboxEnabled === "true" || authDevMailboxEnabled === "1" || authDevMailboxEnabled === "yes") {
    errors.push("AUTH_DEV_MAILBOX_ENABLED must be false in production");
  }

  const smtpPort = Number.parseInt(String(env.get("AUTH_SMTP_PORT") || ""), 10);
  if (Number.isNaN(smtpPort) || smtpPort < 1 || smtpPort > 65535) {
    errors.push("AUTH_SMTP_PORT must be a valid TCP port");
  }

  const smtpSecure = parseBoolean(env.get("AUTH_SMTP_SECURE"));
  if (smtpSecure === null) {
    errors.push("AUTH_SMTP_SECURE must be true/false");
  } else if (smtpSecure === false && smtpPort === 465) {
    errors.push("AUTH_SMTP_SECURE should be true when AUTH_SMTP_PORT=465");
  }

  const smtpSkipVerify = parseBoolean(env.get("AUTH_SMTP_SKIP_VERIFY"));
  if (smtpSkipVerify === true) {
    errors.push("AUTH_SMTP_SKIP_VERIFY must not be enabled in production");
  }

  const smtpRejectUnauthorized = parseBoolean(env.get("AUTH_SMTP_TLS_REJECT_UNAUTHORIZED"));
  if (smtpRejectUnauthorized === false) {
    errors.push("AUTH_SMTP_TLS_REJECT_UNAUTHORIZED must not be false in production");
  }

  const tlsEmail = String(env.get("TLS_EMAIL") || "").trim();
  if (!isLikelyEmail(tlsEmail)) {
    errors.push("TLS_EMAIL must be a valid email address for ACME certificate registration");
  }

  const authMailFrom = String(env.get("AUTH_MAIL_FROM") || "").trim();
  if (!isLikelyEmail(authMailFrom)) {
    errors.push("AUTH_MAIL_FROM must be a valid sender email address");
  }

  if (String(env.get("BETTER_AUTH_SECRET") || "") === String(env.get("MAIL_ENCRYPTION_KEY") || "")) {
    errors.push("BETTER_AUTH_SECRET and MAIL_ENCRYPTION_KEY must be different secrets");
  }

  if (publicDomain === "localhost") {
    warnings.push("PUBLIC_DOMAIN is localhost; use a real domain for external production traffic.");
  }

  if (warnings.length) {
    for (const warning of warnings) {
      console.warn(`[warn] ${warning}`);
    }
  }

  if (errors.length) {
    for (const error of errors) {
      console.error(`[error] ${error}`);
    }
    process.exit(1);
  }

  console.log(`[ok] ${targetPath} passed production environment validation.`);
}

void main();
