#!/bin/bash
# ======================================================================
# Golden Chart - 원격 서버 자동 배포 스크립트
# 대상 서버: exdev.co.kr
# 동작: 로컬 소스 압축 전송 → 서버에서 docker compose up --build
# ======================================================================

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

# 색상
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'

# ── 서버 설정 ──────────────────────────────────────────────────────────
REMOTE_HOST="${REMOTE_HOST:-exdev.co.kr}"
REMOTE_USER="${REMOTE_USER:-aidev}"
REMOTE_PORT="${REMOTE_PORT:-22}"
REMOTE_PROJECT_DIR="${REMOTE_PROJECT_DIR:-/Users/aidev/dev/goldenChart}"
FRONTEND_PORT="${FRONTEND_PORT:-80}"
BACKEND_PORT="${BACKEND_PORT:-8080}"

# ── 옵션 파싱 ──────────────────────────────────────────────────────────
DOWN=false
LOGS=false
STATUS=false
SETUP_SSH=false
SYNC=true
NO_CACHE=true          # 기본: --no-cache (항상 최신 코드)
FORGET_PASSWORD=false
SHELL_ONLY=false
SERVICE=""             # 특정 서비스만 재빌드 (frontend / backend / all)

print_usage() {
  echo "사용법: $0 [옵션]"
  echo ""
  echo "  (기본)                소스 동기화 + 전체 서비스 재빌드 + 재시작"
  echo "  --use-cache           캐시 사용 빌드 (빠름)"
  echo "  --no-sync             파일 동기화 생략"
  echo "  --frontend            프론트엔드만 재빌드"
  echo "  --backend             백엔드만 재빌드"
  echo "  --down, -d            모든 서비스 중지"
  echo "  --logs, -l            전체 로그 스트리밍"
  echo "  --status, -s          서비스 상태 확인"
  echo "  --shell               서버 SSH 세션 열기"
  echo "  --forget-password     SSH 패스워드 캐시 삭제"
  echo "  --help, -h            도움말"
  echo ""
  echo "서버:   ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PORT}"
  echo "경로:   ${REMOTE_PROJECT_DIR}"
  echo "URL:    http://${REMOTE_HOST}:${FRONTEND_PORT}"
}

while [[ $# -gt 0 ]]; do
  case $1 in
    --use-cache)         NO_CACHE=false;        shift ;;
    --no-sync)           SYNC=false;             shift ;;
    --frontend)          SERVICE=frontend;       shift ;;
    --backend)           SERVICE=backend;        shift ;;
    --down|-d)           DOWN=true;              shift ;;
    --logs|-l)           LOGS=true;              shift ;;
    --status|-s)         STATUS=true;            shift ;;
    --shell)             SHELL_ONLY=true;        shift ;;
    --setup-ssh)         SETUP_SSH=true;         shift ;;
    --forget-password)   FORGET_PASSWORD=true;   shift ;;
    --user)              REMOTE_USER="$2";       shift 2 ;;
    --port-ssh)          REMOTE_PORT="$2";       shift 2 ;;
    --help|-h)           print_usage;            exit 0 ;;
    *) echo -e "${RED}알 수 없는 옵션: $1${NC}"; print_usage; exit 1 ;;
  esac
done

SSH_TARGET="${REMOTE_USER}@${REMOTE_HOST}"

# ── 배너 ───────────────────────────────────────────────────────────────
echo -e "${CYAN}${BOLD}"
echo "╔══════════════════════════════════════════════════════════╗"
echo "║           GoldenChart  원격 배포 스크립트                ║"
echo "╚══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "  서버:   ${YELLOW}${SSH_TARGET}:${REMOTE_PORT}${NC}"
echo -e "  경로:   ${YELLOW}${REMOTE_PROJECT_DIR}${NC}"
echo -e "  URL:    ${CYAN}http://${REMOTE_HOST}:${FRONTEND_PORT}${NC}"
echo ""

# ── SSH 패스워드 캐시 ─────────────────────────────────────────────────
PASS_CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/golden-chart-deploy"
PASS_CACHE_FILE="${PASS_CACHE_DIR}/sshpass-${REMOTE_USER}@${REMOTE_HOST}-${REMOTE_PORT}.txt"

if [ "$FORGET_PASSWORD" = true ]; then
  rm -f "$PASS_CACHE_FILE" && echo -e "${GREEN}✓ 패스워드 캐시 삭제${NC}" || echo -e "${YELLOW}캐시 없음${NC}"
fi

SERVER_PASSWORD=""
PASSWORD_FROM_CACHE=false

apply_ssh_cmds() {
  # IdentitiesOnly=yes: ssh-agent의 모든 키를 자동 시도하지 않도록 제한
  # → "Too many authentication failures" 방지
  if [ -n "$SERVER_PASSWORD" ]; then
    export SSHPASS="$SERVER_PASSWORD"
    SSH_CMD="sshpass -e ssh -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -o PubkeyAuthentication=no -p ${REMOTE_PORT}"
    SCP_CMD="sshpass -e scp -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -o PubkeyAuthentication=no -P ${REMOTE_PORT}"
  else
    unset SSHPASS 2>/dev/null || true
    SSH_CMD="ssh -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -p ${REMOTE_PORT}"
    SCP_CMD="scp -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -P ${REMOTE_PORT}"
  fi
}

if command -v sshpass &>/dev/null; then
  if [ -f "$PASS_CACHE_FILE" ]; then
    IFS= read -r SERVER_PASSWORD < "$PASS_CACHE_FILE" || SERVER_PASSWORD=""
    [ -n "$SERVER_PASSWORD" ] && PASSWORD_FROM_CACHE=true && echo -e "${GREEN}✓ 저장된 패스워드 사용 (--forget-password 로 초기화)${NC}"
  fi
  if [ -z "$SERVER_PASSWORD" ]; then
    echo -e "${CYAN}SSH 패스워드 (키 인증 시 Enter):${NC}"
    read -s -p "패스워드: " SERVER_PASSWORD; echo ""
    PASSWORD_FROM_CACHE=false
  fi
else
  echo -e "${YELLOW}sshpass 없음 — SSH 키 인증 모드${NC}"
fi
apply_ssh_cmds

# ── SSH 연결 테스트 ───────────────────────────────────────────────────
echo -e "${CYAN}[연결] SSH 테스트 중...${NC}"
# set -e 영향 차단을 위해 || true 사용
SSH_ERR=$( { $SSH_CMD $SSH_TARGET "exit"; } 2>&1 ) || true
SSH_EC=$( { $SSH_CMD $SSH_TARGET "exit" >/dev/null 2>&1; echo $?; } ) || SSH_EC=1
SSH_EC="${SSH_EC:-1}"

if [ "${SSH_EC}" != "0" ] && [ -n "$SERVER_PASSWORD" ] && [ "$PASSWORD_FROM_CACHE" = true ] && command -v sshpass &>/dev/null; then
  echo -e "${YELLOW}캐시 패스워드 실패 — 재입력:${NC}"
  rm -f "$PASS_CACHE_FILE"
  read -s -p "패스워드: " SERVER_PASSWORD; echo ""
  PASSWORD_FROM_CACHE=false
  apply_ssh_cmds
  SSH_ERR=$( { $SSH_CMD $SSH_TARGET "exit"; } 2>&1 ) || true
  SSH_EC=$( { $SSH_CMD $SSH_TARGET "exit" >/dev/null 2>&1; echo $?; } ) || SSH_EC=1
  SSH_EC="${SSH_EC:-1}"
fi

if [ "${SSH_EC}" != "0" ]; then
  echo -e "${RED}✗ SSH 연결 실패 (exit code: ${SSH_EC})${NC}"
  [ -n "$SSH_ERR" ] && echo -e "${RED}  오류: $(echo "$SSH_ERR" | head -3)${NC}"
  echo ""
  echo -e "${YELLOW}해결 방법:${NC}"
  echo "  1) SSH 키 등록: ssh-copy-id -p ${REMOTE_PORT} ${SSH_TARGET}"
  echo "  2) 직접 테스트: ssh -p ${REMOTE_PORT} ${SSH_TARGET}"
  echo "  3) sshpass 설치 (패스워드 인증): brew install hudochenkov/sshpass/sshpass"
  exit 1
fi

echo -e "${GREEN}✓ SSH 연결 성공${NC}"

# 패스워드 캐시 저장
if [ -n "$SERVER_PASSWORD" ] && [ "$PASSWORD_FROM_CACHE" = false ] && command -v sshpass &>/dev/null; then
  mkdir -p "$PASS_CACHE_DIR"; chmod 700 "$PASS_CACHE_DIR" 2>/dev/null || true
  ( umask 077 && printf '%s' "$SERVER_PASSWORD" > "$PASS_CACHE_FILE" )
  chmod 600 "$PASS_CACHE_FILE" 2>/dev/null || true
  echo -e "${GREEN}✓ 패스워드 캐시 저장됨${NC}"
fi
echo ""

# ── 원격 명령 헬퍼 ────────────────────────────────────────────────────
remote_exec() { $SSH_CMD $SSH_TARGET "bash -l -c $(printf '%q' "$*")"; }

# ── 특수 모드 처리 ────────────────────────────────────────────────────
if [ "$SHELL_ONLY" = true ]; then
  echo -e "${CYAN}서버 SSH 세션 (exit 로 종료):${NC}"
  $SSH_CMD -t $SSH_TARGET "bash -l"; exit 0
fi

if [ "$STATUS" = true ]; then
  echo -e "${CYAN}[상태] 서비스 컨테이너:${NC}"
  remote_exec "cd ${REMOTE_PROJECT_DIR} && docker compose ps"
  echo ""; echo -e "${CYAN}[리소스]:${NC}"
  remote_exec "docker stats --no-stream --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}'"
  exit 0
fi

if [ "$LOGS" = true ]; then
  echo -e "${CYAN}[로그] 전체 서비스 로그 (Ctrl+C 종료):${NC}"
  $SSH_CMD $SSH_TARGET "cd ${REMOTE_PROJECT_DIR} && docker compose logs -f --tail 100"
  exit 0
fi

if [ "$DOWN" = true ]; then
  echo -e "${YELLOW}[중지] 모든 서비스 중지 중...${NC}"
  remote_exec "cd ${REMOTE_PROJECT_DIR} && docker compose down"
  echo -e "${GREEN}✓ 서비스 중지 완료${NC}"; exit 0
fi

# ── [1/3] 파일 동기화 ─────────────────────────────────────────────────
if [ "$SYNC" = true ]; then
  echo -e "${CYAN}[1/3] 소스 → 서버 동기화 중...${NC}"
  TEMP_ARCHIVE="/tmp/gc-deploy-$$.tar.gz"
  echo -e "${YELLOW}  압축 중 (node_modules / .git / dist / target 제외)...${NC}"
  tar --exclude='*/node_modules' \
      --exclude='*/.git' \
      --exclude='*/dist' \
      --exclude='*/target' \
      --exclude='*/.idea' \
      --exclude='*/.vscode' \
      --exclude='*/.cursor' \
      --exclude='*/__MACOSX' \
      --exclude='*/.DS_Store' \
      --exclude='*.log' \
      --exclude='.env.local' \
      --exclude='.env.*.local' \
      -czf "$TEMP_ARCHIVE" .
  echo -e "${YELLOW}  서버 전송 중...${NC}"
  $SCP_CMD "$TEMP_ARCHIVE" "${SSH_TARGET}:/tmp/gc-deploy.tar.gz"
  echo -e "${YELLOW}  서버 기존 소스 정리 후 압축 해제 중...${NC}"
  remote_exec "rm -rf ${REMOTE_PROJECT_DIR} && \
               mkdir -p ${REMOTE_PROJECT_DIR} && \
               cd ${REMOTE_PROJECT_DIR} && \
               tar -xzf /tmp/gc-deploy.tar.gz && \
               rm -f /tmp/gc-deploy.tar.gz"
  rm -f "$TEMP_ARCHIVE"
  echo -e "${GREEN}✓ 파일 동기화 완료${NC}"
else
  echo -e "${CYAN}[1/3] 파일 동기화 생략 — 서버 기존 소스 사용${NC}"
fi
echo ""

# ── Docker 데몬 확인 ──────────────────────────────────────────────────
echo -e "${CYAN}[사전] Docker 데몬 확인 중...${NC}"
if ! remote_exec "docker info >/dev/null 2>&1"; then
  echo -e "${YELLOW}  Docker Desktop 기동 시도 중...${NC}"
  remote_exec "[ -d /Applications/Docker.app ] && open -ga Docker || true"
  for i in $(seq 1 40); do
    sleep 3
    remote_exec "docker info >/dev/null 2>&1" && break
    echo -ne "${YELLOW}  대기 중 ${i}...${NC}\r"
  done
fi
remote_exec "docker info >/dev/null 2>&1" && echo -e "${GREEN}✓ Docker 데몬 준비됨${NC}" || { echo -e "${RED}✗ Docker 데몬 불가${NC}"; exit 1; }
echo ""

# ── [2/3] 빌드 및 재시작 ──────────────────────────────────────────────
[ "$NO_CACHE" = true ] && CACHE_MSG="캐시 없이 (항상 최신 코드 반영)" || CACHE_MSG="캐시 사용 (빠름)"
[ "$NO_CACHE" = true ] && NO_CACHE_FLAG="--no-cache" || NO_CACHE_FLAG=""

if [ -z "$SERVICE" ]; then
  # ── 전체 서비스 재시작 ─────────────────────────────────────────────
  echo -e "${CYAN}[2/3] 전체 서비스 빌드 + 재시작 중... (${CACHE_MSG})${NC}"
  echo -e "${YELLOW}  (mysql, backend, frontend 순서로 시작됨)${NC}"
  remote_exec "cd ${REMOTE_PROJECT_DIR} && \
               docker compose down --remove-orphans && \
               docker compose build ${NO_CACHE_FLAG} && \
               docker compose up -d"
else
  # ── 특정 서비스만 재빌드 ──────────────────────────────────────────
  echo -e "${CYAN}[2/3] ${SERVICE} 서비스만 재빌드 중... (${CACHE_MSG})${NC}"
  remote_exec "cd ${REMOTE_PROJECT_DIR} && \
               docker compose build ${NO_CACHE_FLAG} ${SERVICE} && \
               docker compose up -d ${SERVICE}"
fi

echo -e "${GREEN}✓ 빌드 및 재시작 완료${NC}"
echo ""

# ── [3/3] 서비스 안정화 대기 ──────────────────────────────────────────
echo -e "${CYAN}[3/3] 서비스 기동 대기 중 (최대 90초)...${NC}"
WAIT=0; MAX_WAIT=90
while [ $WAIT -lt $MAX_WAIT ]; do
  RUNNING=$(remote_exec "cd ${REMOTE_PROJECT_DIR} && docker compose ps --status running --format json 2>/dev/null | grep -c 'running' || echo 0" 2>/dev/null || echo "0")
  # 3개 서비스가 모두 running 이면 완료
  TOTAL=$(remote_exec "cd ${REMOTE_PROJECT_DIR} && docker compose ps --format json 2>/dev/null | grep -c 'name' || echo 0" 2>/dev/null || echo "0")
  HTTP_CODE=$(remote_exec "curl -s -o /dev/null -w '%{http_code}' http://localhost:${FRONTEND_PORT}/ 2>/dev/null || echo 000" 2>/dev/null || echo "000")
  echo -ne "  대기 ${WAIT}s — 컨테이너: ${RUNNING}/${TOTAL}, HTTP: ${HTTP_CODE}  \r"
  if echo "$HTTP_CODE" | grep -qE "^2[0-9][0-9]$"; then
    echo ""
    break
  fi
  sleep 5; WAIT=$((WAIT + 5))
done
echo ""

# ── 최종 상태 ─────────────────────────────────────────────────────────
echo -e "${CYAN}[완료] 서비스 상태:${NC}"
remote_exec "cd ${REMOTE_PROJECT_DIR} && docker compose ps"
echo ""

HTTP_CODE=$(remote_exec "curl -s -o /dev/null -w '%{http_code}' http://localhost:${FRONTEND_PORT}/ 2>/dev/null || echo 000" 2>/dev/null || echo "000")
if echo "$HTTP_CODE" | grep -qE "^2[0-9][0-9]$"; then
  echo -e "${GREEN}✓ HTTP ${HTTP_CODE} — 프론트엔드 정상 응답${NC}"
else
  echo -e "${YELLOW}⚠ HTTP ${HTTP_CODE} — 아직 초기화 중일 수 있습니다.${NC}"
  echo -e "${YELLOW}  로그 확인: ./deploy-home.sh --logs${NC}"
fi

BACKEND_HTTP=$(remote_exec "curl -s -o /dev/null -w '%{http_code}' http://localhost:${BACKEND_PORT}/api/indicators/list 2>/dev/null || echo 000" 2>/dev/null || echo "000")
if echo "$BACKEND_HTTP" | grep -qE "^2[0-9][0-9]$"; then
  echo -e "${GREEN}✓ HTTP ${BACKEND_HTTP} — 백엔드 API 정상 응답${NC}"
else
  echo -e "${YELLOW}⚠ 백엔드 HTTP ${BACKEND_HTTP} (Flyway 마이그레이션 실행 중일 수 있음)${NC}"
fi

echo ""
echo -e "${GREEN}${BOLD}╔══════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}${BOLD}║                 배포 완료!  🎉                           ║${NC}"
echo -e "${GREEN}${BOLD}╚══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "  접속 URL:  ${CYAN}${BOLD}http://${REMOTE_HOST}:${FRONTEND_PORT}${NC}"
echo ""
echo -e "${YELLOW}자주 쓰는 명령어:${NC}"
echo "  ./deploy-home.sh                   # 전체 재빌드 배포 (기본)"
echo "  ./deploy-home.sh --use-cache       # 캐시 사용 빌드 (빠름)"
echo "  ./deploy-home.sh --frontend        # 프론트엔드만 재빌드"
echo "  ./deploy-home.sh --backend         # 백엔드만 재빌드"
echo "  ./deploy-home.sh --no-sync         # 서버 기존 소스로 재빌드"
echo "  ./deploy-home.sh --status          # 서비스 상태 확인"
echo "  ./deploy-home.sh --logs            # 전체 로그 보기"
echo "  ./deploy-home.sh --down            # 서비스 중지"
echo "  ./deploy-home.sh --shell           # 서버 SSH 접속"
