#!/bin/sh
set -e

# Block NODE_TLS_REJECT_UNAUTHORIZED=0 in production
if [ "$NODE_ENV" = "production" ] && [ "$NODE_TLS_REJECT_UNAUTHORIZED" = "0" ]; then
  echo "FATAL: NODE_TLS_REJECT_UNAUTHORIZED=0 is not allowed in production"
  exit 1
fi

# Validate critical environment variables
ENV_ERRORS=0
check_env() {
  if [ -z "$2" ] || echo "$2" | grep -q "REQUIRED_STRONG_PASSWORD\|GENERATE_WITH_openssl"; then
    echo "FATAL: $1 is not set or contains a placeholder value"
    ENV_ERRORS=$((ENV_ERRORS + 1))
  fi
}

check_env "DATABASE_URL" "$DATABASE_URL"
check_env "REDIS_URL" "$REDIS_URL"
check_env "JWT_ACCESS_SECRET" "$JWT_ACCESS_SECRET"
check_env "JWT_REFRESH_SECRET" "$JWT_REFRESH_SECRET"
check_env "ENCRYPTION_KEY" "$ENCRYPTION_KEY"
check_env "INITIAL_ADMIN_PASSWORD" "$INITIAL_ADMIN_PASSWORD"

if [ "$ENV_ERRORS" -gt 0 ]; then
  echo ""
  echo "FATAL: $ENV_ERRORS required environment variable(s) missing or invalid."
  echo "Run the configuration wizard:  bash config.sh"
  echo "Or set them manually in .env and restart."
  exit 1
fi

# Fix permissions for mounted volumes (host dirs may be root-owned on first run)
if [ "$(id -u)" = "0" ]; then
  mkdir -p /app/logs /data/geoip /app/uploads 2>/dev/null || true
  chown -R node:node /app/logs /data/geoip /app/uploads 2>/dev/null || true
fi

# Wait for PostgreSQL to be ready before running migrations
echo "Waiting for database..."
MAX_WAIT=30
WAITED=0
until echo "SELECT 1" | npx prisma db execute --stdin --schema ./prisma/schema.prisma 2>/dev/null; do
  sleep 2
  WAITED=$((WAITED + 2))
  if [ $WAITED -ge $MAX_WAIT ]; then
    echo "FATAL: Database not available after ${MAX_WAIT}s"
    exit 1
  fi
done
echo "Database ready (${WAITED}s)"

# Run migrations — fail hard on error (never fall back to db push, which causes drift)
echo "Running Prisma migrations..."
npx prisma migrate deploy 2>&1
echo "Migrations complete."

echo "Running database seed..."
npx prisma db seed 2>&1 || echo "WARNING: Seed failed (non-fatal — seed.ts may require source files not present in production image)"
echo "Seed step done."

# Download MaxMind GeoLite2 database if credentials are provided and DB is missing/stale
if [ -n "$MAXMIND_ACCOUNT_ID" ] && [ -n "$MAXMIND_LICENSE_KEY" ]; then
  GEOIP_DIR="/data/geoip"
  GEOIP_DB="$GEOIP_DIR/GeoLite2-City.mmdb"
  mkdir -p "$GEOIP_DIR" 2>/dev/null || true
  # Re-download weekly (if file is older than 7 days or missing)
  if [ ! -f "$GEOIP_DB" ] || [ "$(find "$GEOIP_DB" -mtime +7 2>/dev/null | wc -l)" -gt 0 ]; then
    echo "Downloading MaxMind GeoLite2-City database..."
    DOWNLOAD_URL="https://download.maxmind.com/geoip/databases/GeoLite2-City/download?suffix=tar.gz"
    # Use Node.js for download (BusyBox wget leaks auth header on redirects)
    if node -e "
      const https = require('https');
      const fs = require('fs');
      setTimeout(() => { console.error('GeoIP download timed out after 60s'); process.exit(1); }, 60000).unref();
      const auth = Buffer.from('$MAXMIND_ACCOUNT_ID:$MAXMIND_LICENSE_KEY').toString('base64');
      const get = (url, cb) => https.get(url, { headers: url.includes('maxmind.com') ? { Authorization: 'Basic ' + auth } : {} }, (res) => {
        if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) return get(res.headers.location, cb);
        if (res.statusCode !== 200) { cb(new Error('HTTP ' + res.statusCode)); return; }
        const out = fs.createWriteStream('/tmp/geolite2.tar.gz');
        res.pipe(out);
        out.on('close', () => cb(null));
      }).on('error', cb);
      get('$DOWNLOAD_URL', (err) => { if (err) { console.error(err.message); process.exit(1); } else { process.exit(0); } });
    "; then
      tar -xzf /tmp/geolite2.tar.gz -C /tmp/ 2>/dev/null
      MMDB_FILE=$(find /tmp -name 'GeoLite2-City.mmdb' -type f 2>/dev/null | head -1)
      if [ -n "$MMDB_FILE" ]; then
        mv "$MMDB_FILE" "$GEOIP_DB"
        echo "GeoLite2-City database updated."
      else
        echo "WARNING: Downloaded archive but no .mmdb file found (non-fatal)"
      fi
      rm -rf /tmp/geolite2.tar.gz /tmp/GeoLite2-City_* 2>/dev/null
    else
      echo "WARNING: Failed to download GeoLite2 database (non-fatal — geo features disabled)"
    fi
  else
    echo "GeoLite2-City database is up to date."
  fi
else
  echo "MaxMind credentials not set — GeoIP lookup disabled."
fi

# If running production mode (node dist/server.js) and dist is stale, recompile
if [ -f "src/server.ts" ] && echo "$@" | grep -q "npm.*start\|node.*dist"; then
  if [ ! -f "dist/server.js" ] || [ "src/server.ts" -nt "dist/server.js" ]; then
    echo "Compiling TypeScript (dist/ is missing or stale)..."
    npx tsc 2>&1 || echo "WARNING: TypeScript compilation had errors"
    echo "Compilation complete."
  fi
fi

echo "Starting server..."
# Drop to node user if running as root (production image uses su-exec)
if [ "$(id -u)" = "0" ] && command -v su-exec >/dev/null 2>&1; then
  exec su-exec node "$@"
else
  exec "$@"
fi
