#!/bin/bash
set -e

DEPLOY_HOME="/home/kjh2064"
PORT_FILE="$DEPLOY_HOME/taxbaik_port"
TIMESTAMP=$(TZ=Asia/Seoul date +%Y%m%d_%H%M%S)

echo "===== 🚀 TaxBaik Green/Blue Deployment Script ====="

if [ "${TAXBAIK_DEPLOY_FROM_CI:-}" != "1" ]; then
  echo "❌ This deployment script may only be run from CI." >&2
  exit 1
fi

# 1. Determine active port
ACTIVE_PORT=5003
if [ -f "$PORT_FILE" ]; then
  ACTIVE_PORT=$(cat "$PORT_FILE" | tr -d '[:space:]')
fi

# 2. Determine target port
TARGET_PORT=5003
if [ "$ACTIVE_PORT" -eq 5003 ]; then
  TARGET_PORT=5004
else
  TARGET_PORT=5003
fi

echo "Active Port: $ACTIVE_PORT"
echo "Target Port: $TARGET_PORT"

# 3. New deploy dir is passed as first argument
DEPLOY_DIR="$1"
if [ -z "$DEPLOY_DIR" ]; then
  echo "Error: Deployment directory argument required"
  exit 1
fi

echo "Deploy Directory: $DEPLOY_DIR"

if [ ! -s "$DEPLOY_DIR/appsettings.Production.json" ]; then
  echo "❌ Missing production settings: $DEPLOY_DIR/appsettings.Production.json" >&2
  exit 1
fi

if [ ! -s "$DEPLOY_DIR/proxy/TaxBaik.Proxy.dll" ]; then
  echo "❌ Missing proxy artifact: $DEPLOY_DIR/proxy/TaxBaik.Proxy.dll" >&2
  exit 1
fi

is_taxbaik_proxy_on_5001() {
  local pids
  pids=$(ss -tlnp 2>/dev/null | grep ':5001 ' | grep -oP 'pid=\K\d+' | sort -u || true)
  [ -n "$pids" ] || return 1

  for pid in $pids; do
    if tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null | grep -q 'TaxBaik.Proxy.dll'; then
      return 0
    fi
  done

  return 1
}

# 0. Ensure the local TCP proxy exists and is running.
# Nginx and external traffic always enter through 127.0.0.1:5001.
if ss -tln | grep -q ':5001 ' && ! is_taxbaik_proxy_on_5001; then
  echo "⚠️ Port 5001 is occupied by a non-proxy process. Attempting to stop legacy taxbaik.service..."
  echo "   Current listener:" >&2
  ss -tlnp 2>/dev/null | grep ':5001 ' >&2 || true

  if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet taxbaik 2>/dev/null; then
    if command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
      sudo -n systemctl stop taxbaik || true
      sudo -n systemctl disable taxbaik || true
      sleep 2
    else
      echo "   sudo -n is unavailable; cannot stop legacy taxbaik.service automatically." >&2
    fi
  fi

  if ss -tln | grep -q ':5001 ' && ! is_taxbaik_proxy_on_5001; then
    echo "❌ Port 5001 is still occupied by a non-proxy process. Abort deploy to avoid routing traffic to the wrong app." >&2
    echo "   Expected: TaxBaik.Proxy.dll on 127.0.0.1:5001" >&2
    echo "   Manual fix: sudo systemctl stop taxbaik && sudo systemctl disable taxbaik" >&2
    ss -tlnp 2>/dev/null | grep ':5001 ' >&2 || true
    exit 1
  fi
fi

if ! is_taxbaik_proxy_on_5001; then
  echo "=== Starting proxy on 127.0.0.1:5001 ==="
  cd "$DEPLOY_DIR/proxy"
  nohup /usr/bin/dotnet TaxBaik.Proxy.dll > "$DEPLOY_HOME/taxbaik_proxy.log" 2>&1 &
  sleep 2
fi

if ! is_taxbaik_proxy_on_5001; then
  echo "❌ Proxy on 127.0.0.1:5001 is not running. Abort deploy." >&2
  ss -tlnp 2>/dev/null | grep ':5001 ' >&2 || true
  exit 1
fi

# 4. Start the new app on the target port
echo "=== Starting New App on Port $TARGET_PORT ==="
cd "$DEPLOY_DIR"
export ASPNETCORE_ENVIRONMENT=Production
export ASPNETCORE_URLS="http://127.0.0.1:$TARGET_PORT"
export ConnectionStrings__Default="Host=localhost;Database=taxbaikdb;Username=taxbaik;Password=taxbaik123"
export DOTNET_PRINT_TELEMETRY_MESSAGE=false

# Run dotnet process
nohup /usr/bin/dotnet TaxBaik.Web.dll > "web_${TARGET_PORT}.log" 2>&1 &
NEW_PID=$!
sleep 2

# Verify process is running
if ! ps -p $NEW_PID > /dev/null; then
  echo "❌ Failed to start dotnet process on port $TARGET_PORT"
  exit 1
fi

# 5. Enhanced Health Check Loop (Razor Pages 기준 검증)
echo "=== Enhanced Health Checking Port $TARGET_PORT ==="
ATTEMPTS=20
SUCCESS=false

for i in $(seq 1 $ATTEMPTS); do
  # 기본 헬스 체크
  HEALTH_STATUS=$(curl -sf -o /dev/null -w '%{http_code}' "http://127.0.0.1:${TARGET_PORT}/healthz" 2>/dev/null || echo "000")

  # 관리자 로그인 페이지 검증 (Cookie Auth + Razor Pages 기준)
  LOGIN_STATUS=$(curl -sf -o /dev/null -w '%{http_code}' "http://127.0.0.1:${TARGET_PORT}/admin/login" 2>/dev/null || echo "000")

  if [ "$HEALTH_STATUS" = "200" ] && [ "$LOGIN_STATUS" = "200" ]; then
    echo "✓ All health checks passed on port $TARGET_PORT (Attempt $i/$ATTEMPTS)"
    echo "   ✓ /healthz: $HEALTH_STATUS"
    echo "   ✓ /admin/login: $LOGIN_STATUS"
    SUCCESS=true
    break
  fi

  if [ $i -eq 1 ] || [ $((i % 5)) -eq 0 ]; then
    echo "  Waiting for health check... ($i/$ATTEMPTS)"
    echo "    /healthz: $HEALTH_STATUS | /admin/login: $LOGIN_STATUS"
  fi

  sleep 2
done

if [ "$SUCCESS" = "false" ]; then
  echo "❌ Enhanced health check failed on port $TARGET_PORT"
  echo "   /healthz: $HEALTH_STATUS | /admin/login: $LOGIN_STATUS"
  echo ""
  echo "Log output (last 30 lines):"
  tail -30 "web_${TARGET_PORT}.log" 2>/dev/null || echo "No log file"
  echo ""
  echo "🔙 Rolling back..."
  kill -9 $NEW_PID || true
  exit 1
fi

# 6. Pre-Switch Validation (포트 전환 전 최종 검증)
echo "=== Pre-Switch Validation ==="

# 6.1 로그 파일에서 FATAL/ERROR 확인
echo "  Checking logs for critical errors..."
if grep -i "fatal\|unhandled exception" "web_${TARGET_PORT}.log" 2>/dev/null; then
  echo "❌ Critical errors found in application logs"
  echo "🔙 Rolling back..."
  kill -9 $NEW_PID || true
  exit 1
fi
echo "  ✓ No critical errors in logs"

# 6.2 Nginx 설정 검증
echo "  Checking Nginx configuration..."
NGINX_TEST_LOG=$(mktemp)
if command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
  if ! sudo -n nginx -t >"$NGINX_TEST_LOG" 2>&1; then
    echo "❌ Nginx configuration is invalid"
    tail -50 "$NGINX_TEST_LOG" 2>/dev/null || true
    rm -f "$NGINX_TEST_LOG"
    echo "🔙 Rolling back..."
    kill -9 $NEW_PID || true
    exit 1
  fi
  echo "  ✓ Nginx configuration is valid"
else
  echo "  ⚠️ Skipping Nginx validation: sudo -n unavailable in this environment"
fi
rm -f "$NGINX_TEST_LOG"

# 6.3 프로세스가 여전히 실행 중인지 확인
if ! ps -p $NEW_PID > /dev/null; then
  echo "❌ New process has terminated unexpectedly"
  echo "🔙 Rolling back..."
  exit 1
fi
echo "  ✓ New process is running (PID: $NEW_PID)"

echo "✓ All pre-switch validations passed"
echo ""

# 7. Switch Traffic
# Nginx never needs per-deploy changes: it always proxies to the persistent
# TaxBaik.Proxy on 127.0.0.1:5001, which reads this same PORT_FILE and
# forwards to whichever port is currently active. See CLAUDE.md section 6.
echo "=== Switching Traffic to Port $TARGET_PORT ==="
echo "$TARGET_PORT" > "$PORT_FILE"
echo "✓ Traffic routed to $TARGET_PORT (via TaxBaik.Proxy on 5001)"

# 7. Terminate Old App
echo "=== Stopping Old App on Port $ACTIVE_PORT ==="
# Find PID listening on ACTIVE_PORT
OLD_PID=$(ss -tlnp | grep ":$ACTIVE_PORT " | grep -oP 'pid=\K\d+' | head -n1)
if [ -n "$OLD_PID" ]; then
  echo "Killing old process PID: $OLD_PID"
  kill -15 $OLD_PID || kill -9 $OLD_PID
  echo "✓ Old process terminated"
else
  echo "No old process found on port $ACTIVE_PORT"
fi

# 8. Cleanup old deployment directories (Keep last 5)
echo "=== Cleaning Up Old Deployments ==="
ls -1dt $DEPLOY_HOME/deployments/taxbaik_* 2>/dev/null | tail -n +6 | xargs rm -rf 2>/dev/null || true
echo "✓ Cleanup completed"

echo "===== ✅ Green/Blue Deployment Completed Successfully ====="
