name: Deploy to Production

on:
  push:
    branches:
      - main
  workflow_dispatch:

concurrency:
  group: deploy-prod-main
  cancel-in-progress: true

env:
  DEPLOY_HOST: 178.104.200.7
  DEPLOY_USER: kjh2064
  SERVICE_NAME: quantengine
  DOTNET_VERSION: '10.0.x'
  QUANTENGINE_DB_NAME: quantenginedb
  QUANTENGINE_DB_USER: quantengine_app
  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
    timeout-minutes: 15

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - 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
          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

      - name: Run Unit Tests
        run: |
          dotnet test src/dotnet/QuantEngine.Core.Tests/QuantEngine.Core.Tests.csproj \
            -c Release \
            --no-build

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

      - 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/wwwroot
          printf '{\n  "version": "1.0.%s-%s",\n  "built": "%s"\n}\n' "${{ github.run_number }}" "$COMMIT_HASH" "$BUILD_TIME" > ./publish/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
          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: Prepare QuantEngine DB Env
        run: |
          mkdir -p ./deploy
          cat > ./deploy/quantengine.env <<EOF
          ConnectionStrings__DefaultConnection=Host=127.0.0.1;Database=${QUANTENGINE_DB_NAME};Username=${QUANTENGINE_DB_USER};Password=${{ secrets.QUANTENGINE_DB_PASSWORD }};Search Path=quantengine;
          EOF
          chmod 600 ./deploy/quantengine.env

      - name: Package Artifact
        run: |
          tar -czf quantengine.tar.gz -C ./publish .
          echo "✓ Package size: $(du -sh quantengine.tar.gz | 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 }}"

          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) ==="

          ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
            "$DEPLOY_USER@$DEPLOY_HOST" "mkdir -p /home/kjh2064/tmp"
          scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
            quantengine.tar.gz "$DEPLOY_USER@$DEPLOY_HOST:/home/kjh2064/tmp/quantengine.tar.gz"
          scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
            tools/deploy_quantengine.sh "$DEPLOY_USER@$DEPLOY_HOST:/home/kjh2064/tmp/deploy.sh"
          scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
            deploy/quantengine.env "$DEPLOY_USER@$DEPLOY_HOST:/home/kjh2064/tmp/quantengine.env"

          ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
            "$DEPLOY_USER@$DEPLOY_HOST" "chmod +x /home/kjh2064/tmp/deploy.sh && CI_DEPLOY=1 /home/kjh2064/tmp/deploy.sh"

          ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 \
            "$DEPLOY_USER@$DEPLOY_HOST" "mkdir -p /home/kjh2064/.config && install -m 600 /home/kjh2064/tmp/quantengine.env /home/kjh2064/.config/quantengine.env && rm -f /home/kjh2064/tmp/quantengine.env"

          echo "=== Verifying Loopback Health ==="
          loopback_headers=$(ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ~/.ssh/id_ed25519 "$DEPLOY_USER@$DEPLOY_HOST" "curl -s -D - -o /dev/null http://127.0.0.1:5000/")
          echo "$loopback_headers"
          if ! printf '%s' "$loopback_headers" | grep -qE '^HTTP/1\.[01] 30[12] '; then
            echo "Loopback health check failed for quantengine" >&2
            exit 1
          fi
          if ! printf '%s' "$loopback_headers" | grep -qiE '^Location: /login'; then
            echo "Loopback redirect target is unexpected" >&2
            exit 1
          fi

          echo "=== Verifying Favicon Assets ==="
          favicon_svg_code=$(curl -s -o /dev/null -w "%{http_code}" "https://quant.taxbaik.com/favicon.svg")
          favicon_png_code=$(curl -s -o /dev/null -w "%{http_code}" "https://quant.taxbaik.com/favicon.png")
          echo "/favicon.svg -> ${favicon_svg_code}"
          echo "/favicon.png -> ${favicon_png_code}"
          if [ "$favicon_svg_code" != "200" ] && [ "$favicon_png_code" != "200" ]; then
            echo "Favicon assets are not reachable after deploy" >&2
            exit 1
          fi

          echo "=== Verifying Public Routes ==="
          public_root_headers=$(curl -s -D - -o /dev/null "https://quant.taxbaik.com/")
          login_headers=$(curl -s -D - -o /dev/null "https://quant.taxbaik.com/login")

          public_root_code=$(printf '%s' "$public_root_headers" | awk 'NR==1 {print $2}')
          login_code=$(printf '%s' "$login_headers" | awk 'NR==1 {print $2}')

          echo "https://quant.taxbaik.com/ -> ${public_root_code}"
          echo "https://quant.taxbaik.com/login -> ${login_code}"

          if [ "$public_root_code" != "302" ] && [ "$public_root_code" != "200" ]; then
            echo "Deployment content check failed for public root" >&2
            exit 1
          fi
          if [ "$login_code" != "200" ]; then
            echo "Deployment content check failed for login page" >&2
            exit 1
          fi

          echo "✓ 배포 완료: quantengine_${TIMESTAMP} @ $DEPLOY_HOST"
          send_telegram "✅ <b>QuantEngine 배포 완료</b>

          커밋: <code>${COMMIT}</code>
          시간: <code>${TIMESTAMP}</code>
          대상: <code>${DEPLOY_HOST}</code>"
