#!/usr/bin/env bash
# =============================================================================
# run.sh — SBV ISO 20022 API Gateway
# Ngân hàng Nhà nước Việt Nam
#
# Cách dùng:
#   ./run.sh            → build + start production
#   ./run.sh dev        → ts-node (không cần build)
#   ./run.sh test       → chạy toàn bộ Jest tests
#   ./run.sh test:watch → Jest watch mode
#   ./run.sh build      → chỉ compile TypeScript
#   ./run.sh lint       → ESLint kiểm tra source
#   ./run.sh health     → curl health check endpoint
#   ./run.sh demo       → gửi request IBPS migrate demo
#   ./run.sh stop       → dừng gateway đang chạy (PID file)
# =============================================================================

set -euo pipefail

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

PORT="${PORT:-8080}"
HOST="${HOST:-127.0.0.1}"
PID_FILE="$SCRIPT_DIR/.gateway.pid"
LOG_FILE="$SCRIPT_DIR/gateway.log"
CMD="${1:-start}"

# ─── Màu sắc terminal ──────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; CYAN='\033[0;36m'; RESET='\033[0m'; BOLD='\033[1m'

log()  { echo -e "${CYAN}[SBV-GW]${RESET} $*"; }
ok()   { echo -e "${GREEN}  ✓${RESET}  $*"; }
warn() { echo -e "${YELLOW}  ⚠${RESET}  $*"; }
err()  { echo -e "${RED}  ✗${RESET}  $*" >&2; }
sep()  { echo -e "${BLUE}──────────────────────────────────────────${RESET}"; }

# ─── Kiểm tra Node.js ─────────────────────────────────────────────────────────
check_node() {
  if ! command -v node &>/dev/null; then
    err "Node.js không tìm thấy. Cài đặt: apt install nodejs -y"
    exit 1
  fi
  NODE_VER=$(node --version)
  ok "Node.js $NODE_VER"

  if ! command -v npm &>/dev/null; then
    err "npm không tìm thấy."
    exit 1
  fi
  ok "npm $(npm --version)"
}

# ─── Cài dependencies nếu chưa có ────────────────────────────────────────────
ensure_deps() {
  if [[ ! -d node_modules ]]; then
    log "Cài dependencies..."
    npm install --silent
    ok "Dependencies đã cài"
  fi
}

# ─── Build TypeScript ─────────────────────────────────────────────────────────
do_build() {
  log "Biên dịch TypeScript..."
  npx tsc
  ok "Build hoàn thành → dist/"
}

# ─── Dừng gateway đang chạy ───────────────────────────────────────────────────
do_stop() {
  local killed=0

  # 1. Kill theo PID file nếu có
  if [[ -f "$PID_FILE" ]]; then
    PID=$(cat "$PID_FILE")
    if kill -0 "$PID" 2>/dev/null; then
      kill -9 "$PID" 2>/dev/null || true
      ok "Gateway (PID $PID) đã dừng"
      killed=1
    fi
    rm -f "$PID_FILE"
  fi

  # 2. Luôn kill mọi tiến trình còn đang giữ port (phòng trường hợp stale)
  PIDS=$(lsof -ti TCP:"$PORT" 2>/dev/null || true)
  if [[ -n "$PIDS" ]]; then
    echo "$PIDS" | xargs -r kill -9 2>/dev/null || true
    ok "Đã giải phóng port $PORT"
    killed=1
  fi

  [[ $killed -eq 0 ]] && warn "Không có tiến trình nào trên port $PORT"
  sleep 0.5   # đợi kernel release port
}

# ─── MAIN ─────────────────────────────────────────────────────────────────────
sep
echo -e "${BOLD}  SBV ISO 20022 Gateway  v1.0.0${RESET}"
sep

check_node
ensure_deps

case "$CMD" in

  # ── Kill port sạch (không start lại) ────────────────────────────────────────
  killport)
    do_stop
    ;;

  # ── Production: stop trước → build → start foreground ───────────────────────
  start)
    do_stop
    do_build
    log "Khởi động gateway tại http://${HOST}:${PORT} ..."
    echo ""
    PORT="$PORT" HOST="$HOST" node dist/index.js
    ;;

  # ── Background: stop trước → build → start nền, ghi PID ────────────────────
  bg|background)
    do_stop
    do_build
    log "Khởi động gateway (background) tại http://${HOST}:${PORT} ..."
    PORT="$PORT" HOST="$HOST" nohup node dist/index.js >> "$LOG_FILE" 2>&1 &
    GW_PID=$!
    echo "$GW_PID" > "$PID_FILE"
    sleep 1
    if kill -0 "$GW_PID" 2>/dev/null; then
      ok "Gateway chạy nền — PID $GW_PID"
      ok "Log: $LOG_FILE"
      ok "Dừng: ./run.sh stop"
    else
      err "Gateway không khởi động được. Xem log: $LOG_FILE"
      exit 1
    fi
    ;;

  # ── Dev: stop trước → ts-node ────────────────────────────────────────────────
  dev)
    do_stop
    log "Dev mode — ts-node (hot reload không cần build)"
    PORT="$PORT" HOST="$HOST" npx ts-node src/index.ts
    ;;

  # ── Test: chạy Jest ─────────────────────────────────────────────────────────
  test)
    log "Chạy test suite..."
    echo ""
    npx jest --verbose --runInBand
    ;;

  # ── Test watch mode ──────────────────────────────────────────────────────────
  test:watch)
    npx jest --verbose --watch
    ;;

  # ── Chỉ build ────────────────────────────────────────────────────────────────
  build)
    do_build
    ;;

  # ── Lint ─────────────────────────────────────────────────────────────────────
  lint)
    log "ESLint..."
    npx eslint src --ext .ts && ok "Lint passed"
    ;;

  # ── Stop ─────────────────────────────────────────────────────────────────────
  stop)
    do_stop
    ;;

  # ── Health check ─────────────────────────────────────────────────────────────
  health)
    URL="http://${HOST}:${PORT}/api/v1/iso20022/health"
    log "GET $URL"
    curl -sf "$URL" | python3 -m json.tool
    ;;

  # ── Demo: gửi IBPS migrate request ───────────────────────────────────────────
  demo)
    URL="http://${HOST}:${PORT}/api/v1/iso20022/ibps-migrate"
    log "POST $URL (IBPS → ISO 20022 demo)"
    curl -sf -X POST "$URL" \
      -H "Content-Type: application/json" \
      -d '{
        "IBPS_MSG_ID":       "MSG20241215001234",
        "TRANS_DATE":        "20241215",
        "TRANS_TIME":        "093045",
        "SENDER_BNK_CODE":   "970436",
        "RECEIVER_BNK_CODE": "970415",
        "SENDER_ACCT":       "1400123456789",
        "RECEIVER_ACCT":     "1234567890001",
        "SENDER_NAME":       "NGUYEN VAN AN",
        "RECEIVER_NAME":     "TRAN THI BINH",
        "AMOUNT":            "5000000000",
        "CONTENT":           "Chuyen khoan mua hang hoa thang 12/2024",
        "TRANS_TYPE":        "10"
      }' | python3 -m json.tool
    ;;

  *)
    echo "Lệnh không hợp lệ: $CMD"
    echo ""
    echo "Cách dùng: ./run.sh [start|bg|dev|test|test:watch|build|lint|stop|killport|health|demo]"
    exit 1
    ;;
esac
