# =============================================================================
# WOOO TECH - Momo Pro System
# GitLab CI/CD Pipeline
# =============================================================================
#
# 流程:
#   1. test: 執行 pytest 測試
#   2. security: Bandit 安全掃描
#   3. build: 構建 Docker 映像並推送到 Registry
#   4. deploy-uat: 部署到 UAT 環境
#   5. deploy-gcp: 部署到 GCP 環境 (手動觸發)
#
# Registry:
#   - URL: registry.wooo.work
#   - 帳號: GitLab CI/CD 變數 REGISTRY_USER
#   - 密碼: GitLab CI/CD 變數 REGISTRY_PASSWORD
#
# =============================================================================

stages:
  - test
  - build
  - deploy

variables:
  # Docker Registry
  REGISTRY_URL: "registry.wooo.work"
  IMAGE_NAME: "wooo/momo-pro-system"
  IMAGE_PATH: "${REGISTRY_URL}/${IMAGE_NAME}"

  # 目標環境
  UAT_HOST: "192.168.0.110"
  UAT_USER: "wooo"
  GCP_HOST: "35.194.233.141"
  GCP_USER: "ogt"

# =============================================================================
# Test Stage
# =============================================================================
test:
  stage: test
  image: python:3.11-slim
  before_script:
    - pip install --quiet -r requirements.txt
    - pip install --quiet pytest pytest-cov
  script:
    - python -m pytest tests/ -v --tb=short || echo "No tests or tests skipped"
  allow_failure: true
  tags:
    - docker
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push"'
    - if: '$CI_PIPELINE_SOURCE == "web"'

# =============================================================================
# Security Scan (Bandit)
# =============================================================================
security-scan:
  stage: test
  image: python:3.11-slim
  before_script:
    - pip install --quiet bandit
  script:
    - bandit -r . -x ./tests,./venv -f json -o bandit-report.json || true
    - |
      if [ -f bandit-report.json ]; then
        HIGH=$(cat bandit-report.json | python3 -c "import sys,json; print(len([r for r in json.load(sys.stdin).get('results',[]) if r.get('issue_severity')=='HIGH']))" 2>/dev/null || echo "0")
        echo "High severity issues: $HIGH"
        if [ "$HIGH" -gt "0" ]; then
          echo "⚠️ 發現高危安全問題"
        fi
      fi
  artifacts:
    paths:
      - bandit-report.json
    expire_in: 1 week
  allow_failure: true
  tags:
    - docker

# =============================================================================
# Build & Push to Registry
# =============================================================================
build:
  stage: build
  image: docker:24.0.7
  services:
    - docker:24.0.7-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - echo "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin $REGISTRY_URL
  script:
    - echo "Building image..."
    - BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    - docker build --build-arg BUILD_DATE=$BUILD_DATE --build-arg GIT_SHA=$CI_COMMIT_SHA -t $IMAGE_PATH:$CI_COMMIT_SHORT_SHA -t $IMAGE_PATH:latest .
    - echo "Pushing to registry..."
    - docker push $IMAGE_PATH:$CI_COMMIT_SHORT_SHA
    - docker push $IMAGE_PATH:latest
    - echo "Image pushed - $IMAGE_PATH:latest"
  after_script:
    - if [ -n "$TELEGRAM_BOT_TOKEN" ] && [ "$CI_JOB_STATUS" = "success" ]; then curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" -d chat_id="${TELEGRAM_CHAT_ID}" -d parse_mode="HTML" -d text="Build Success - ${IMAGE_PATH}:${CI_COMMIT_SHORT_SHA}" > /dev/null 2>&1; fi
  tags:
    - docker
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'

# =============================================================================
# Deploy to UAT
# =============================================================================
deploy-uat:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh-client curl
    - mkdir -p ~/.ssh
    - echo "$UAT_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - ssh-keyscan -H $UAT_HOST >> ~/.ssh/known_hosts 2>/dev/null
  script:
    - echo "🚀 部署到 UAT..."
    - |
      ssh -o StrictHostKeyChecking=no ${UAT_USER}@${UAT_HOST} << ENDSSH
        # 設定 kubectl 環境
        export KUBECONFIG=/home/wooo/.kube/config

        # 同步程式碼
        cd /home/wooo/momo_pro_system
        git fetch gitlab main
        git reset --hard gitlab/main

        # 更新 K8s registry secret
        kubectl delete secret registry-secret -n momo 2>/dev/null || true
        kubectl create secret docker-registry registry-secret \
          --docker-server=${REGISTRY_URL} \
          --docker-username=${REGISTRY_USER} \
          --docker-password=${REGISTRY_PASSWORD} \
          -n momo

        # 重啟服務 (會自動拉取新映像)
        kubectl rollout restart deployment/momo-app deployment/momo-scheduler -n momo

        # 等待就緒
        kubectl rollout status deployment/momo-app -n momo --timeout=180s
        echo "✅ UAT 部署完成"
      ENDSSH
    - |
      # 健康檢查
      sleep 10
      if curl -s "https://mo.wooo.work/health" | grep -q "healthy"; then
        echo "✅ 健康檢查通過"
      else
        echo "⚠️ 健康檢查失敗"
      fi
  after_script:
    - |
      if [ -n "$TELEGRAM_BOT_TOKEN" ]; then
        if [ "$CI_JOB_STATUS" == "success" ]; then
          curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
            -d chat_id="${TELEGRAM_CHAT_ID}" \
            -d parse_mode="HTML" \
            -d text="✅ <b>UAT 部署成功</b>%0A%0A🌐 https://mo.wooo.work%0A📌 ${CI_COMMIT_SHORT_SHA}%0A👤 ${GITLAB_USER_NAME}" > /dev/null 2>&1
        else
          curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
            -d chat_id="${TELEGRAM_CHAT_ID}" \
            -d parse_mode="HTML" \
            -d text="❌ <b>UAT 部署失敗</b>%0A%0A🔗 ${CI_PIPELINE_URL}" > /dev/null 2>&1
        fi
      fi
  tags:
    - docker
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
  needs:
    - build

# =============================================================================
# Deploy to GCP (手動觸發)
# =============================================================================
deploy-gcp:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh-client curl docker
    - mkdir -p ~/.ssh
    - echo "$GCP_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
    - ssh-keyscan -H $GCP_HOST >> ~/.ssh/known_hosts 2>/dev/null
  script:
    - echo "🚀 部署到 GCP..."
    - |
      # 從 Registry 拉取映像
      echo "$REGISTRY_PASSWORD" | docker login -u "$REGISTRY_USER" --password-stdin $REGISTRY_URL
      docker pull $IMAGE_PATH:latest

      # 匯出映像
      docker save $IMAGE_PATH:latest -o /tmp/momo-image.tar

      # 傳輸到 GCP (使用用戶家目錄)
      scp -o StrictHostKeyChecking=no /tmp/momo-image.tar ${GCP_USER}@${GCP_HOST}:~/momo-image.tar

      # 在 GCP 上匯入並部署
      ssh -o StrictHostKeyChecking=no ${GCP_USER}@${GCP_HOST} << ENDSSH
        # 匯入映像到 K3s
        sudo k3s ctr images import ~/momo-image.tar
        rm ~/momo-image.tar

        # 更新 Deployment 使用新映像
        sudo kubectl set image deployment/momo-app momo-app=${IMAGE_PATH}:latest -n momo
        sudo kubectl set image deployment/momo-scheduler scheduler=${IMAGE_PATH}:latest -n momo

        # 設定 imagePullPolicy 為 IfNotPresent（允許使用本地匯入的映像）
        sudo kubectl patch deployment momo-app -n momo -p '{"spec":{"template":{"spec":{"containers":[{"name":"momo-app","imagePullPolicy":"IfNotPresent"}]}}}}'
        sudo kubectl patch deployment momo-scheduler -n momo -p '{"spec":{"template":{"spec":{"containers":[{"name":"scheduler","imagePullPolicy":"IfNotPresent"}]}}}}'

        # 等待部署完成
        sudo kubectl rollout status deployment/momo-app -n momo --timeout=180s

        echo "✅ GCP 部署完成"
      ENDSSH
    - |
      # 健康檢查
      sleep 10
      if curl -s "https://momo.wooo.work/health" | grep -q "healthy"; then
        echo "✅ GCP 健康檢查通過"
      else
        echo "⚠️ GCP 健康檢查失敗"
      fi
  after_script:
    - |
      if [ -n "$TELEGRAM_BOT_TOKEN" ]; then
        if [ "$CI_JOB_STATUS" == "success" ]; then
          curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
            -d chat_id="${TELEGRAM_CHAT_ID}" \
            -d parse_mode="HTML" \
            -d text="✅ <b>GCP 部署成功</b>%0A%0A🌐 https://momo.wooo.work%0A📌 ${CI_COMMIT_SHORT_SHA}" > /dev/null 2>&1
        fi
      fi
  tags:
    - docker
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
  needs:
    - deploy-uat
  allow_failure: false

# =============================================================================
# Health Check (手動)
# =============================================================================
health-check:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache curl
  script:
    - echo "🏥 健康檢查..."
    - echo "UAT:" && curl -s "https://mo.wooo.work/health" || echo "無法連線"
    - echo "GCP:" && curl -s "https://momo.wooo.work/health" || echo "無法連線"
    - echo "Registry:" && curl -s -u "$REGISTRY_USER:$REGISTRY_PASSWORD" "https://$REGISTRY_URL/v2/_catalog" || echo "無法連線"
  tags:
    - docker
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
      when: manual
