name: Deploy to Production

on:
  push:
    branches: [ main ]
  workflow_dispatch:

env:
  DEPLOY_HOST: 172.17.0.1
  DEPLOY_USER: kjh2064
  DEPLOY_PATH: /home/kjh2064/quantengine_active
  SERVICE_NAME: quantengine
  DOTNET_VERSION: '10.0.x'
  TELEGRAM_BOT_TOKEN_DEFAULT: "8734507814:AAFyacLMai8GB4K-hQ_Nd3t3D01A-h1ZdV0"
  TELEGRAM_CHAT_ID_DEFAULT: "-5460205872"

jobs:
  build-and-deploy:
    name: Build & Deploy to Production
    runs-on: ubuntu-latest

    steps:
    - name: Checkout Code
      uses: actions/checkout@v3
      with:
        fetch-depth: 0

    - name: Setup .NET
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: ${{ env.DOTNET_VERSION }}

    - name: Setup Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.10'

    - name: Install Python Dependencies
      run: pip install pyyaml openpyxl requests

    - name: "[GATE] Run Core Validations"
      run: |
        echo "🔐 Running critical CI validations..."
        python3 tools/validate_no_direct_api_trading_v1.py || exit 1
        python3 tools/validate_specs.py || exit 1
        echo "✅ All critical validations passed"

    - name: Ensure Temp Directory and Mock Packet
      run: |
        mkdir -p Temp
        # 빈 패킷 객체를 생성하여 dotnet test/run 시 IO Exception 방어
        if [ ! -f Temp/final_decision_packet_active.json ]; then
          echo '{"active_decision": "PASS", "details": "CI dummy packet"}' > Temp/final_decision_packet_active.json
        fi

    - name: Restore Dependencies
      run: dotnet restore src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj

    - name: Build Release
      run: |
        dotnet build src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj \
          -c Release \
          --no-restore \
          -p:Version=1.0.${{ github.run_number }}

    - name: Run Unit Tests
      run: |
        if [ -d tests/unit ]; then
          dotnet test tests/unit \
            -c Release \
            --no-build \
            || echo "⚠️ Some tests failed (non-blocking for web service)"
        fi

    - name: Publish Release Package
      run: |
        dotnet publish src/dotnet/QuantEngine.Web/QuantEngine.Web.csproj \
          -c Release \
          --no-build \
          -o ./publish-output

    - name: Generate Build Info
      run: |
        COMMIT_HASH=$(git rev-parse --short HEAD)
        BUILD_TIME=$(date -d "+9 hours" +'%Y-%m-%d %H:%M:%S KST')
        mkdir -p ./publish-output/wwwroot
        printf '{\n  "version": "1.0.%s-%s",\n  "built": "%s"\n}\n' "${{ github.run_number }}" "$COMMIT_HASH" "$BUILD_TIME" > ./publish-output/wwwroot/version.json
        echo "✓ Generated version info: 1.0.${{ github.run_number }}-$COMMIT_HASH @ $BUILD_TIME"


    - name: Setup SSH
      run: |
        mkdir -p ~/.ssh
        chmod 700 ~/.ssh
        # SSH_PRIVATE_KEY가 평문 PEM이든 base64든 유연하게 처리
        if echo "${{ secrets.SSH_PRIVATE_KEY }}" | grep -q "BEGIN"; then
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
        else
          echo "${{ secrets.SSH_PRIVATE_KEY }}" | base64 -d > ~/.ssh/id_ed25519 || echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
        fi
        chmod 600 ~/.ssh/id_ed25519
        ssh-keyscan -H ${{ env.DEPLOY_HOST }} >> ~/.ssh/known_hosts 2>/dev/null || true

    - name: Package Artifact
      run: |
        tar -czf quant_engine_deploy.tgz -C ./publish-output .
        echo "✓ Package size: $(du -sh quant_engine_deploy.tgz | cut -f1)"

    - name: Deploy & Verify on Server
      run: |
        set -e
        TIMESTAMP=$(date +%Y%m%d_%H%M%S)
        COMMIT=$(git rev-parse --short HEAD)
        DEPLOY_HOST="${{ env.DEPLOY_HOST }}"
        DEPLOY_USER="${{ env.DEPLOY_USER }}"
        
        # 텔레그램 설정 바인딩 (Secret에 없을 경우 기본값 백업 사용)
        TELEGRAM_BOT_TOKEN="${{ secrets.TELEGRAM_BOT_TOKEN }}"
        [ -z "$TELEGRAM_BOT_TOKEN" ] && TELEGRAM_BOT_TOKEN="${{ env.TELEGRAM_BOT_TOKEN_DEFAULT }}"
        TELEGRAM_CHAT_ID="${{ secrets.TELEGRAM_CHAT_ID }}"
        [ -z "$TELEGRAM_CHAT_ID" ] && TELEGRAM_CHAT_ID="${{ env.TELEGRAM_CHAT_ID_DEFAULT }}"

        send_telegram() {
          local text="$1"
          curl -fsS -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
            -d "chat_id=${TELEGRAM_CHAT_ID}" \
            --data-urlencode "text=${text}" \
            -d "parse_mode=HTML" >/dev/null || true
        }

        notify_failure() {
          local exit_code=$?
          send_telegram "❌ <b>QuantEngine 배포 실패</b>
          
          커밋: <code>${COMMIT}</code>
          시간: <code>${TIMESTAMP}</code>
          단계: deploy-to-prod (SSH Execution)"
          exit "$exit_code"
        }

        trap notify_failure ERR

        echo "=== Deploying QuantEngine $COMMIT ($TIMESTAMP) ==="

        # 1. 아티팩트 복사
        scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
          quant_engine_deploy.tgz "$DEPLOY_USER@$DEPLOY_HOST:/tmp/quantengine_${TIMESTAMP}.tgz"

        # 2. 원격 배포 명령어 통합 (SSH 1회 연결)
        ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
          -o ServerAliveInterval=10 \
          "$DEPLOY_USER@$DEPLOY_HOST" bash << REMOTE
        set -e
        DEPLOY_HOME="/home/kjh2064"
        DEPLOY_DIR="\$DEPLOY_HOME/deployments/quantengine_${TIMESTAMP}"
        
        echo "--- [1/4] 압축 해제 ---"
        mkdir -p "\$DEPLOY_DIR"
        tar -xzf "/tmp/quantengine_${TIMESTAMP}.tgz" -C "\$DEPLOY_DIR"
        rm -f "/tmp/quantengine_${TIMESTAMP}.tgz"

        echo "--- [2/4] 심볼릭 링크 전환 ---"
        ln -sfn "\$DEPLOY_DIR" "${{ env.DEPLOY_PATH }}"

        echo "--- [3/4] 서비스 재시작 ---"
        sudo /usr/bin/systemctl restart ${{ env.SERVICE_NAME }}

        echo "--- [4/4] 헬스 체크 ---"
        ATTEMPTS=20
        for i in \$(seq 1 \$ATTEMPTS); do
          STATUS=\$(curl -sf -o /dev/null -w '%{http_code}' http://127.0.0.1:5000/ 2>/dev/null || echo "000")
          if [ "\$STATUS" = "200" ]; then
            echo "✓ 헬스체크 성공 (시도 \$i/\$ATTEMPTS, HTTP 200)"
            # 구 배포 폴더 정리 (최근 5개만 보존)
            ls -1dt \$DEPLOY_HOME/deployments/quantengine_* 2>/dev/null | tail -n +6 | xargs rm -rf 2>/dev/null || true
            exit 0
          fi
          if [ "\$i" -eq "\$ATTEMPTS" ]; then
            echo "=== FATAL: 서비스가 헬스체크 응답을 하지 않음 ===" >&2
            systemctl is-active ${{ env.SERVICE_NAME }} >&2 || true
            journalctl -u ${{ env.SERVICE_NAME }} --no-pager -n 50 >&2
            exit 1
          fi
          echo "  대기 중... (\$i/\$ATTEMPTS, HTTP \$STATUS)"
          sleep 3
        done
        REMOTE

        echo "✓ 배포 완료: quantengine_${TIMESTAMP} @ $DEPLOY_HOST"
        send_telegram "✅ <b>QuantEngine 배포 완료</b>
        
        커밋: <code>${COMMIT}</code>
        시간: <code>${TIMESTAMP}</code>
        대상: <code>${DEPLOY_HOST}</code>"
