#!/usr/bin/env bash
# ============================================================
# WBX Spring Core — 프로덕션 배포 스크립트 (Linux)
# 사용법: sudo ./scripts/deploy-prod.sh
# ============================================================
set -euo pipefail

# ---------- 색상 ----------
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
ok()   { echo -e "  ${GREEN}[OK]${NC} $1"; }
warn() { echo -e "  ${YELLOW}[WARN]${NC} $1"; }
fail() { echo -e "  ${RED}[FAIL]${NC} $1"; exit 1; }
info() { echo -e "  ${CYAN}[INFO]${NC} $1"; }

APP_DIR="/opt/wbx-app"
SERVICE_USER="wbxapp"
SERVICE_NAME="wbx-app"
JAR_NAME="app.jar"

echo ""
echo "=========================================="
echo " WBX Spring Core — 프로덕션 배포"
echo "=========================================="
echo ""

# ---------- Root 권한 ----------
if [ "$EUID" -ne 0 ]; then
    fail "root 권한이 필요합니다: sudo $0"
fi

# ---------- 1. 서비스 계정 ----------
echo "1. 서비스 계정 (${SERVICE_USER})"
if id "$SERVICE_USER" &>/dev/null; then
    ok "이미 존재"
else
    useradd -r -m -s /bin/bash "$SERVICE_USER"
    ok "생성 완료"
fi

# ---------- 2. 타임존/로케일 ----------
echo "2. 시스템 설정"
timedatectl set-timezone Asia/Seoul 2>/dev/null && ok "타임존: Asia/Seoul" || warn "타임존 설정 실패 — 수동 확인"

# ---------- 3. 디렉토리 ----------
echo "3. 디렉토리 구조"
mkdir -p "${APP_DIR}"/{logs,uploads,backup}
chown -R "${SERVICE_USER}:${SERVICE_USER}" "${APP_DIR}"
ok "${APP_DIR}/{logs,uploads,backup}"

# ---------- 4. 시스템 리밋 ----------
echo "4. 파일 디스크립터 리밋"
LIMITS_FILE="/etc/security/limits.d/${SERVICE_USER}.conf"
if [ ! -f "$LIMITS_FILE" ]; then
    cat > "$LIMITS_FILE" << EOF
${SERVICE_USER} soft nofile 65535
${SERVICE_USER} hard nofile 65535
EOF
    ok "${LIMITS_FILE} 생성"
else
    ok "이미 존재"
fi

# ---------- 5. JAR 복사 ----------
echo "5. JAR 배포"
JAR_SOURCE="build/libs/wbx-spring-core-*.jar"
FOUND_JAR=$(ls $JAR_SOURCE 2>/dev/null | head -1)

if [ -z "$FOUND_JAR" ]; then
    warn "JAR 파일 없음 — 먼저 ./gradlew bootJar 실행 필요"
else
    # 이전 버전 백업
    if [ -f "${APP_DIR}/${JAR_NAME}" ]; then
        cp "${APP_DIR}/${JAR_NAME}" "${APP_DIR}/backup/${JAR_NAME}.$(date +%Y%m%d_%H%M%S)"
        info "이전 JAR 백업 완료"
    fi
    cp "$FOUND_JAR" "${APP_DIR}/${JAR_NAME}"
    chown "${SERVICE_USER}:${SERVICE_USER}" "${APP_DIR}/${JAR_NAME}"
    ok "$(basename "$FOUND_JAR") → ${APP_DIR}/${JAR_NAME}"
fi

# ---------- 6. .env 템플릿 ----------
echo "6. 환경변수 파일"
if [ ! -f "${APP_DIR}/.env" ]; then
    cat > "${APP_DIR}/.env" << 'ENVEOF'
# ===== WBX Spring Core — 프로덕션 환경변수 =====

SPRING_PROFILES_ACTIVE=prod,mysql
SERVER_CONTEXT_PATH=/

# JWT (필수 변경!)
JWT_SECRET=your-production-secret-key-minimum-256-bits-long

# DB
DB_HOST=localhost
DB_PORT=3306
DB_NAME=wbx_spring
DB_USER=wbxapp
DB_PASS=StrongP@ss

# Redis
SPRING_DATA_REDIS_HOST=localhost

# CORS
CORS_ORIGINS=https://app.company.com

# 로그
LOG_PATH=/opt/wbx-app/logs/app.log
ENVEOF
    chown "${SERVICE_USER}:${SERVICE_USER}" "${APP_DIR}/.env"
    chmod 600 "${APP_DIR}/.env"
    ok "${APP_DIR}/.env 생성 (값을 반드시 수정하세요!)"
else
    ok "이미 존재 — 건너뜀"
fi

# ---------- 7. systemd 서비스 ----------
echo "7. systemd 서비스"
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
cat > "$SERVICE_FILE" << EOF
[Unit]
Description=WBX Spring Application
After=network.target

[Service]
Type=simple
User=${SERVICE_USER}
WorkingDirectory=${APP_DIR}
EnvironmentFile=${APP_DIR}/.env
ExecStart=/usr/bin/java \\
  -XX:+UseG1GC \\
  -XX:MaxRAMPercentage=75.0 \\
  -Dspring.profiles.active=\${SPRING_PROFILES_ACTIVE} \\
  -jar ${APP_DIR}/${JAR_NAME}
Restart=always
RestartSec=5
StandardOutput=append:${APP_DIR}/logs/app.log
StandardError=append:${APP_DIR}/logs/app.log

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable "$SERVICE_NAME" --quiet
ok "${SERVICE_FILE}"

# ---------- 8. 백업 cron ----------
echo "8. DB 백업 cron"
BACKUP_SCRIPT="${APP_DIR}/backup/db-backup.sh"
if [ ! -f "$BACKUP_SCRIPT" ]; then
    cat > "$BACKUP_SCRIPT" << 'CRONEOF'
#!/usr/bin/env bash
# WBX Spring — DB 백업 (crontab: 0 2 * * *)
set -euo pipefail
source /opt/wbx-app/.env
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/opt/wbx-app/backup"

mysqldump -h"${DB_HOST}" -u"${DB_USER}" -p"${DB_PASS}" "${DB_NAME}" \
  | gzip > "${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz"

# 30일 이상 백업 삭제
find "${BACKUP_DIR}" -name '*.gz' -mtime +30 -delete

echo "[$(date)] backup done: ${DB_NAME}_${DATE}.sql.gz"
CRONEOF
    chmod +x "$BACKUP_SCRIPT"
    chown "${SERVICE_USER}:${SERVICE_USER}" "$BACKUP_SCRIPT"
    ok "${BACKUP_SCRIPT} 생성"

    # crontab 등록
    CRON_LINE="0 2 * * * ${BACKUP_SCRIPT} >> ${APP_DIR}/logs/backup.log 2>&1"
    (crontab -u "$SERVICE_USER" -l 2>/dev/null | grep -v "db-backup.sh"; echo "$CRON_LINE") \
        | crontab -u "$SERVICE_USER" -
    ok "crontab 등록 (매일 02:00)"
else
    ok "이미 존재 — 건너뜀"
fi

# ---------- 9. 방화벽 ----------
echo "9. 방화벽"
if command -v firewall-cmd &>/dev/null; then
    firewall-cmd --permanent --add-service=http  --quiet 2>/dev/null || true
    firewall-cmd --permanent --add-service=https --quiet 2>/dev/null || true
    firewall-cmd --reload --quiet 2>/dev/null || true
    ok "HTTP/HTTPS 허용"
else
    warn "firewalld 없음 — 수동으로 방화벽 설정 필요"
fi

# ---------- 10. SELinux ----------
echo "10. SELinux"
if command -v setsebool &>/dev/null && getenforce 2>/dev/null | grep -qi enforcing; then
    setsebool -P httpd_can_network_connect 1 2>/dev/null
    ok "httpd_can_network_connect = 1"
else
    info "SELinux 비활성 또는 미설치 — 건너뜀"
fi

# ---------- 결과 ----------
echo ""
echo "=========================================="
echo -e " ${GREEN}배포 준비 완료${NC}"
echo ""
echo " 체크리스트:"
echo "   [ ] ${APP_DIR}/.env 값 수정 (JWT_SECRET, DB_PASS 필수!)"
echo "   [ ] DB 생성 + 사용자 권한 부여"
echo "   [ ] Redis 설치 + bind 127.0.0.1 + requirepass"
echo "   [ ] JAR 빌드: ./gradlew bootJar"
echo "   [ ] 서비스 시작: sudo systemctl start ${SERVICE_NAME}"
echo "   [ ] 확인: curl http://localhost:8080/actuator/health"
echo "   [ ] 리버스 프록시 설정 (Nginx/Caddy)"
echo "   [ ] SSL 인증서 설치"
echo "=========================================="
echo ""
