#!/usr/bin/env bash
# Apply production URLs from node/.env.production.example to node/.env
# while keeping existing secrets (DB password, JWT, OAuth keys, SMTP, etc.).
#
# Run on the production server before deploy:
#   bash scripts/sync-production-env.sh
#   bash scripts/check-production-env.sh
#   sudo bash scripts/deploy.sh --svn
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
ENV_FILE="$ROOT/node/.env"
EXAMPLE_FILE="$ROOT/node/.env.production.example"

die() { echo "Error: $1" >&2; exit 1; }

[[ -f "$EXAMPLE_FILE" ]] || die "$EXAMPLE_FILE not found"
[[ -f "$ENV_FILE" ]] || die "$ENV_FILE not found — copy from $EXAMPLE_FILE first"

BACKUP="${ENV_FILE}.bak.$(date +%Y%m%d%H%M%S)"
cp "$ENV_FILE" "$BACKUP"
echo "Backed up existing env to $(basename "$BACKUP")"

export ENV_FILE EXAMPLE_FILE
node <<'NODE'
const fs = require('fs');

const envFile = process.env.ENV_FILE;
const exampleFile = process.env.EXAMPLE_FILE;

function parseEnv(content) {
  const out = {};
  for (const line of content.split('\n')) {
    const trimmed = line.trim();
    if (!trimmed || trimmed.startsWith('#')) continue;
    const eq = trimmed.indexOf('=');
    if (eq === -1) continue;
    const key = trimmed.slice(0, eq).trim();
    let val = trimmed.slice(eq + 1).trim();
    if (
      (val.startsWith('"') && val.endsWith('"')) ||
      (val.startsWith("'") && val.endsWith("'"))
    ) {
      val = val.slice(1, -1);
    }
    out[key] = val;
  }
  return out;
}

const existing = parseEnv(fs.readFileSync(envFile, 'utf8'));
const example = parseEnv(fs.readFileSync(exampleFile, 'utf8'));

const forceFromExample = new Set([
  'NODE_ENV',
  'PORT',
  'APP_URL',
  'BOOKING_APP_URL',
  'API_URL',
  'GOOGLE_REDIRECT_URI',
  'GOOGLE_AUTH_REDIRECT_URI',
  'LINKEDIN_AUTH_REDIRECT_URI',
  'MICROSOFT_REDIRECT_URI',
  'EMBED_SCRIPT_URL',
  'CORS_ALLOWED_ORIGINS',
]);

const secretKeys = new Set([
  'DB_HOST',
  'DB_PORT',
  'DB_USER',
  'DB_PASSWORD',
  'DB_NAME',
  'DB_POOL_SIZE',
  'DATABASE_URL',
  'JWT_SECRET',
  'JWT_EXPIRES_IN',
  'GOOGLE_CLIENT_ID',
  'GOOGLE_CLIENT_SECRET',
  'LINKEDIN_CLIENT_ID',
  'LINKEDIN_CLIENT_SECRET',
  'MICROSOFT_CLIENT_ID',
  'MICROSOFT_CLIENT_SECRET',
  'TOKEN_ENCRYPTION_KEY',
  'SMTP_HOST',
  'SMTP_PORT',
  'SMTP_USER',
  'SMTP_PASS',
  'EMAIL_FROM',
  'KAFKA_BROKERS',
  'KAFKA_CLIENT_ID',
  'REDIS_HOST',
  'REDIS_PORT',
  'REDIS_PASSWORD',
  'MAIL_TRANSPORT',
  'GMAIL_REFRESH_TOKEN',
  'GMAIL_USER',
]);

const merged = { ...example };

for (const [key, value] of Object.entries(existing)) {
  if (forceFromExample.has(key)) continue;
  if (secretKeys.has(key) && value) {
    merged[key] = value;
  } else if (!(key in merged) && value) {
    merged[key] = value;
  }
}

const order = [
  'NODE_ENV',
  'PORT',
  'APP_URL',
  'BOOKING_APP_URL',
  'API_URL',
  '',
  'DATABASE_URL',
  'DB_HOST',
  'DB_PORT',
  'DB_USER',
  'DB_PASSWORD',
  'DB_NAME',
  'DB_POOL_SIZE',
  '',
  'KAFKA_BROKERS',
  'KAFKA_CLIENT_ID',
  '',
  'REDIS_HOST',
  'REDIS_PORT',
  'REDIS_PASSWORD',
  '',
  'JWT_SECRET',
  'JWT_EXPIRES_IN',
  '',
  'GOOGLE_CLIENT_ID',
  'GOOGLE_CLIENT_SECRET',
  'GOOGLE_REDIRECT_URI',
  'GOOGLE_AUTH_REDIRECT_URI',
  '',
  'LINKEDIN_CLIENT_ID',
  'LINKEDIN_CLIENT_SECRET',
  'LINKEDIN_AUTH_REDIRECT_URI',
  '',
  'MICROSOFT_CLIENT_ID',
  'MICROSOFT_CLIENT_SECRET',
  'MICROSOFT_REDIRECT_URI',
  '',
  'TOKEN_ENCRYPTION_KEY',
  '',
  'SMTP_HOST',
  'SMTP_PORT',
  'SMTP_USER',
  'SMTP_PASS',
  'EMAIL_FROM',
  'MAIL_TRANSPORT',
  'GMAIL_REFRESH_TOKEN',
  'GMAIL_USER',
  '',
  'EMBED_SCRIPT_URL',
  'CORS_ALLOWED_ORIGINS',
];

const written = new Set();
const lines = ['# Production environment — synced by scripts/sync-production-env.sh', ''];

function formatValue(key, value) {
  if (!value) return '';
  if (/[^A-Za-z0-9_@:/.-]/.test(value)) {
    return `${key}='${String(value).replace(/'/g, `'\\''`)}'`;
  }
  return `${key}=${value}`;
}

for (const key of order) {
  if (key === '') {
    lines.push('');
    continue;
  }
  if (key in merged) {
    const line = formatValue(key, merged[key]);
    if (line) lines.push(line);
    written.add(key);
  }
}

for (const key of Object.keys(merged).sort()) {
  if (!written.has(key)) {
    const line = formatValue(key, merged[key]);
    if (line) lines.push(line);
  }
}

fs.writeFileSync(envFile, `${lines.join('\n')}\n`);
console.log('Updated', envFile);
console.log('  NODE_ENV=', merged.NODE_ENV);
console.log('  APP_URL=', merged.APP_URL);
console.log('  API_URL=', merged.API_URL);
console.log('  GOOGLE_AUTH_REDIRECT_URI=', merged.GOOGLE_AUTH_REDIRECT_URI);
NODE

bash "$ROOT/scripts/check-production-env.sh" "$ENV_FILE"
echo ""
echo "Production env synced. Redeploy with:"
echo "  sudo bash scripts/deploy.sh --svn"
