name: Validators (Pull Requests Only)

on:
  pull_request:
    branches: [ main ]
  workflow_dispatch:

# Phase 3: Validator pipeline
# Main branch push validation moved to merge-to-main.yml
# This workflow runs validators only on PRs for feedback

jobs:
  validate-core:
    runs-on: ubuntu-latest

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

    - name: Configure Runtime Paths
      run: |
        # Node.js 18: /usr/local/bin (appstore symlink)
        export PATH=/usr/local/bin:$PATH
        echo "/usr/local/bin" >> $GITHUB_PATH
        echo "=== 런타임 확인 ==="
        /usr/bin/python3 --version
        node --version
        npm --version

    - name: Setup Python Environment
      run: |
        # 순수 Python 패키지만 설치 (numpy/pandas 제외 — ARMv7l 휠 없음)
        VENV_BASE=$HOME/python_venv
        REQ_HASH=$(md5sum tools/validate_specs.py 2>/dev/null | cut -d' ' -f1 || echo "default")
        VENV="$VENV_BASE/$REQ_HASH"

        if [ ! -f "$VENV/bin/python" ]; then
          echo "=== venv 신규 생성: $REQ_HASH ==="
          mkdir -p "$VENV_BASE"
          /usr/bin/python3 -m venv "$VENV"

          # venv 내 pip 확인 및 복구
          if [ ! -f "$VENV/bin/pip" ]; then
            echo "pip missing in venv, installing via get-pip.py..."
            curl -sS https://bootstrap.pypa.io/pip/3.8/get-pip.py -o get-pip.py
            "$VENV/bin/python" get-pip.py --quiet
            rm get-pip.py
          fi

          "$VENV/bin/pip" install --upgrade pip --quiet
          "$VENV/bin/pip" install requests pyyaml openpyxl --quiet

          # 오래된 venv 정리 (최근 2개만 유지)
          ls -dt "$VENV_BASE"/*/ 2>/dev/null | tail -n +3 | xargs rm -rf 2>/dev/null || true
        else
          echo "=== venv 캐시 히트: $("$VENV/bin/python" --version 2>&1) ==="
          "$VENV/bin/python" - <<'PY'
          import importlib
          for mod in ("requests", "yaml", "openpyxl"):
              importlib.import_module(mod)
          print("venv dependency import check: PASS")
          PY
        fi
        echo "$VENV/bin" >> $GITHUB_PATH

    - name: Install Node Dependencies
      run: |
        # package-lock.json 해시로 캐시 유효성 판단
        CACHE_BASE=/volume1/gitea/node_cache
        LOCK_HASH=$(md5sum package-lock.json 2>/dev/null | cut -d' ' -f1 || echo "no-lock")
        [ -z "$LOCK_HASH" ] && LOCK_HASH="no-lock"
        CACHE_DIR="$CACHE_BASE/$LOCK_HASH"

        if [ -d "$CACHE_DIR/node_modules" ]; then
          echo "=== node_modules 캐시 히트: $LOCK_HASH ==="
          # 이미 같은 캐시를 가리키고 있으면 재연결하지 않음
          if [ -L node_modules ] && [ "$(readlink node_modules)" = "$CACHE_DIR/node_modules" ]; then
            echo "=== node_modules already linked to cache ==="
          else
            if [ -e node_modules ] || [ -L node_modules ]; then
              rm -rf node_modules
            fi
            ln -s "$CACHE_DIR/node_modules" node_modules
          fi
        else
          echo "=== npm install (최초 or lock 변경) ==="
          npm install --quiet
          # 캐시 저장
          mkdir -p "$CACHE_DIR"
          cp -r node_modules "$CACHE_DIR/node_modules"
          echo "캐시 저장 완료: $CACHE_DIR"
          # 오래된 캐시 정리 (최근 3개만 유지)
          ls -dt "$CACHE_BASE"/*/  2>/dev/null | tail -n +4 | xargs rm -rf 2>/dev/null || true
        fi
        node --version && npm --version

    - name: "[CRITICAL] No Direct API Trading Gate"
      run: python3 tools/validate_no_direct_api_trading_v1.py

    - name: "[CRITICAL] Validate KIS API Credentials (mock)"
      env:
        KIS_APP_Key_TEST: ${{ vars.KIS_APP_KEY_TEST }}
        KIS_APP_Secret_TEST: ${{ vars.KIS_APP_SECRET_TEST }}
      run: python3 tools/validate_kis_api_credentials_v1.py --account mock --ticker 005930 --dry-run

    - name: Validate Specs
      run: python3 tools/validate_specs.py

    - name: Validate Formula Registry
      run: python3 tools/validate_formula_registry.py

    - name: Validate Golden Case Coverage
      run: python3 tools/validate_golden_coverage_100.py

    - name: Validate Harness Coverage Audit
      run: python3 tools/harness_coverage_auditor.py

    - name: Validate Platform Transition WBS
      run: python3 tools/validate_platform_transition_wbs_v1.py

    - name: Build Calibration Priority Backlog
      run: python3 tools/build_calibration_priority_v1.py

    - name: Build Calibration Change Ledger
      run: python3 tools/build_calibration_change_ledger_v4.py

    - name: Validate Calibration Change Ledger
      run: python3 tools/validate_calibration_change_ledger_v1.py

    - name: Validate Qualitative Sell Strategy Pipeline
      run: python3 tools/validate_qualitative_sell_strategy_pipeline_v1.py

    - name: Validate Gitea Secrets Contract
      run: python3 tools/validate_gitea_secrets_contract_v1.py

    - name: Validate Snapshot Admin Workflow
      run: python3 tools/validate_snapshot_admin_workflow_v1.py

    - name: Validate DB First Pipeline
      run: python3 tools/validate_db_first_pipeline_v1.py

    - name: Update Proposal Evaluation History
      run: python3 tools/update_proposal_evaluation_history.py --json GatherTradingData.json --history Temp/proposal_evaluation_history.json

    - name: Build Performance Readiness Replay Bridge
      run: python3 tools/build_performance_readiness_replay_bridge_v1.py --hist Temp/proposal_evaluation_history.json --out Temp/performance_readiness_replay_bridge_v1.json

    - name: Build Outcome Quality Score
      run: python3 tools/build_outcome_quality_score_v1.py --json GatherTradingData.json --out Temp/outcome_quality_score_v1.json --policy spec/strategy_execution_lock_policy.yaml

    - name: Build Trade Quality From T5
      run: python3 tools/build_trade_quality_from_t5_v1.py --hist Temp/proposal_evaluation_history.json --out Temp/trade_quality_from_t5_v1.json

    - name: Build Operational Alpha Calibration
      run: python3 tools/build_operational_alpha_calibration_v2.py --out Temp/operational_alpha_calibration_v2.json

    - name: Validate Operational Alpha Calibration
      run: python3 tools/validate_operational_alpha_calibration_v2.py --input Temp/operational_alpha_calibration_v2.json --out Temp/validate_operational_alpha_calibration_v2.json

    - name: Build Operational T20 Outcome Ledger
      run: python3 tools/build_operational_t20_outcome_ledger_v1.py --json GatherTradingData.json --out Temp/operational_t20_outcome_ledger_v1.json

    - name: Validate Live Data Activation Gate
      run: python3 tools/validate_live_data_activation_gate_v1.py

    - name: Ensure Temp Directory and Mock Packet
      run: |
        mkdir -p Temp
        if [ ! -f Temp/final_decision_packet_active.json ]; then
          echo '{"formula_id":"FINAL_DECISION_PACKET_V2","meta":{"generated_at":"2026-06-29T00:00:00Z"},"canonical_metrics":{},"portfolio_snapshot":{},"order_table":[]}' > Temp/final_decision_packet_active.json
        fi

    - name: Validate Replay Live Separation
      run: python3 tools/validate_replay_live_separation_v1.py

    - name: Render Final Decision Packet V4
      run: dotnet run --project src/dotnet/QuantEngine.Tools/QuantEngine.Tools.csproj -- packet-v4 --packet=Temp/final_decision_packet_active.json --out=Temp/final_decision_packet_v4.json

    - name: Render Operational Report
      run: dotnet run --project src/dotnet/QuantEngine.Tools/QuantEngine.Tools.csproj -- report --packet=Temp/final_decision_packet_active.json --out=Temp/operational_report.json

    - name: Validate Report Packet Sync
      run: python3 tools/validate_report_packet_sync_v1.py --packet Temp/final_decision_packet_active.json --report Temp/operational_report.json | tee Temp/validate_report_packet_sync_v1.json

    - name: Validate Report Section Completeness
      run: python3 tools/validate_report_section_completeness_v1.py

    - name: Validate JSON Generator Outputs
      run: python3 tools/validate_json_generator_outputs_v1.py

    - name: Generate PostgreSQL History Schema
      run: python3 tools/generate_postgresql_history_schema_v1.py

    - name: Validate PostgreSQL History Contract
      run: python3 tools/validate_postgresql_history_contract_v1.py

    - name: Package Operational Report Artifacts
      run: tar -czf Temp/operational-report-artifacts.tar.gz Temp/operational_report.json Temp/operational_report.md Temp/missing_data_inventory_v1.json Temp/report_section_completeness.json Temp/operational_alpha_calibration_v2.json Temp/validate_operational_alpha_calibration_v2.json Temp/operational_t20_outcome_ledger_v1.json Temp/live_data_activation_gate_v1.json Temp/replay_live_separation_v1.json Temp/validate_report_packet_sync_v1.json Temp/json_generator_outputs_v1.json Temp/proposal_evaluation_history.json Temp/performance_readiness_replay_bridge_v1.json Temp/postgresql_history_schema_v1.sql Temp/postgresql_history_schema_v1.json Temp/postgresql_history_contract_v1.json

    - name: Upload Operational Report Artifacts
      uses: actions/upload-artifact@v3
      with:
        name: operational-report-artifacts
        path: Temp/operational-report-artifacts.tar.gz

    - name: Upload Operational Report JSON
      uses: actions/upload-artifact@v3
      with:
        name: operational-report-json
        path: Temp/operational_report.json

  validate-ui-and-storage:
    runs-on: ubuntu-latest
    needs: validate-core
    if: github.event_name != 'push'

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

    - name: Setup Python Environment
      run: |
        VENV_BASE=$HOME/python_venv
        REQ_HASH=$(md5sum tools/validate_snapshot_admin_web_v1.py 2>/dev/null | cut -d' ' -f1 || echo "default")
        VENV="$VENV_BASE/$REQ_HASH"

        if [ ! -f "$VENV/bin/python" ]; then
          echo "=== venv 신규 생성: $REQ_HASH ==="
          mkdir -p "$VENV_BASE"
          /usr/bin/python3 -m venv "$VENV"

          if [ ! -f "$VENV/bin/pip" ]; then
            echo "pip missing in venv, installing via get-pip.py..."
            curl -sS https://bootstrap.pypa.io/pip/3.8/get-pip.py -o get-pip.py
            "$VENV/bin/python" get-pip.py --quiet
            rm get-pip.py
          fi

          "$VENV/bin/pip" install --upgrade pip --quiet
          "$VENV/bin/pip" install requests pyyaml openpyxl --quiet
        else
          echo "=== venv 캐시 히트: $("$VENV/bin/python" --version 2>&1) ==="
        fi
        echo "$VENV/bin" >> $GITHUB_PATH

    - name: Validate Snapshot Admin Web UI
      if: needs.validate-core.result == 'success'
      run: python3 tools/validate_snapshot_admin_web_v1.py

    - name: Validate Storage Backend Contracts
      if: needs.validate-core.result == 'success'
      run: python3 -m pytest tests/unit/test_storage_backend_v1.py tests/unit/test_validate_kis_api_credentials_v1.py tests/unit/test_qualitative_sell_strategy_store_v1.py tests/unit/test_kis_api_client_v1.py tests/unit/test_snapshot_admin_store_v1.py tests/unit/test_snapshot_admin_web_v1.py -q

    - name: Notify PR Result
      if: always() && github.event_name == 'pull_request'
      env:
        CORE_RESULT: ${{ needs.validate-core.result }}
        STAGE_RESULT: ${{ job.status }}
      run: |
        STATUS="$STAGE_RESULT"
        if [ "$CORE_RESULT" != "success" ]; then
          STATUS="failure"
        fi
        PR_NUM="${{ github.event.pull_request.number }}"
        RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
        if [ "$STATUS" = "success" ]; then
          MSG="✅ **CI PASS** — spec/registry/coverage gate OK\n\n[워크플로우 로그](${RUN_URL})"
        else
          MSG="❌ **CI FAIL** — 로그 확인 필요\n\n[워크플로우 로그](${RUN_URL})"
        fi
        curl -s -X POST "${{ github.api_url }}/repos/${{ github.repository }}/issues/${PR_NUM}/comments" \
          -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
          -H "Content-Type: application/json" \
          -d "{\"body\":\"${MSG}\"}"
