name: Code Analysis and Production Deploy

on:
  pull_request:
  push:
    branches: [ main, dev ]

jobs:
  analyze:
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - name: Workspace sanity check
        run: |
          echo "PWD: $(pwd)"
          echo "LS:"
          ls -la
          echo "Lockfiles:"
          ls -la package-lock.json || true

      - name: Node versions
        run: |
          node -v
          npm -v

      - name: gitleaks (Secrets Scanning)
        run: |
          # Try to get the latest release asset URL
          ASSET_URL=$(curl -s https://api.github.com/repos/gitleaks/gitleaks/releases/latest | grep -o '"browser_download_url": "[^"]*linux_x64[^"]*"' | head -1 | cut -d'"' -f4)
          if [ -z "$ASSET_URL" ]; then
            # Fallback: construct URL manually
            VERSION=$(curl -s https://api.github.com/repos/gitleaks/gitleaks/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
            ASSET_URL="https://github.com/gitleaks/gitleaks/releases/download/${VERSION}/gitleaks_${VERSION}_linux_x64.tar.gz"
          fi
          echo "Downloading from: $ASSET_URL"
          curl -sSL -L "$ASSET_URL" -o gitleaks.tar.gz
          # Check if download was successful and file is not HTML
          if [ ! -s gitleaks.tar.gz ] || head -1 gitleaks.tar.gz | grep -q "<!DOCTYPE html"; then
            echo "Error: Downloaded file is not a valid archive (might be HTML page)"
            head -5 gitleaks.tar.gz
            exit 1
          fi
          # Extract ONLY the gitleaks binary (the archive also contains README etc. which would trigger gitleaks itself)
          if tar -tzf gitleaks.tar.gz >/dev/null 2>&1; then
            tar -xzf gitleaks.tar.gz gitleaks
          elif tar -tf gitleaks.tar.gz >/dev/null 2>&1; then
            tar -xf gitleaks.tar.gz gitleaks
          else
            echo "Error: Cannot extract archive. File type:"
            file gitleaks.tar.gz
            exit 1
          fi
          chmod +x gitleaks
          # Run gitleaks scan BEFORE installing dependencies to avoid false positives from node_modules
          ./gitleaks detect --source . --no-git --verbose --exit-code 1
          rm -f gitleaks.tar.gz

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Unit tests
        run: npm test

      - name: Build
        run: npm run build --if-present

      - name: Semgrep (SAST)
        run: semgrep --config p/default --error .

      - name: npm audit (high+)
        run: npm audit --audit-level=high

      - name: OSV-Scanner (SCA)
        run: |
          curl -L -o osv-scanner https://github.com/google/osv-scanner/releases/latest/download/osv-scanner_linux_amd64
          chmod +x osv-scanner
          ./osv-scanner --version
          test -f ./package-lock.json
          ./osv-scanner --lockfile ./package-lock.json

  deploy-production:
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    steps:
      - name: Prepare SSH
        run: |
          set -euo pipefail

          mkdir -p ~/.ssh
          printf "%s" "${{ secrets.PROD_SSH_KEY }}" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan -p "${{ vars.PROD_PORT }}" "${{ vars.PROD_HOST }}" >> ~/.ssh/known_hosts

      - name: Test SSH connection
        run: |
          ssh -i ~/.ssh/id_ed25519 \
            -o StrictHostKeyChecking=no \
            -o BatchMode=yes \
            -p "${{ vars.PROD_PORT }}" \
            "${{ vars.PROD_USER }}@${{ vars.PROD_HOST }}" \
            "echo SSH OK"

      - name: Run production deployment script
        run: |
          ssh -i ~/.ssh/id_ed25519 \
            -o BatchMode=yes \
            -p "${{ vars.PROD_PORT }}" \
            "${{ vars.PROD_USER }}@${{ vars.PROD_HOST }}" \
            "bash -lc 'cd /var/www/harheimertc && git fetch origin main && git checkout -B main origin/main && git reset --hard origin/main && ./deploy-production.sh'"

  deploy-test:
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
    steps:
      - name: Prepare SSH
        run: |
          set -euo pipefail

          mkdir -p ~/.ssh
          printf "%s" "${{ secrets.PROD_SSH_KEY }}" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan -p "${{ vars.PROD_PORT }}" "${{ vars.PROD_HOST }}" >> ~/.ssh/known_hosts

      - name: Test SSH connection
        run: |
          ssh -i ~/.ssh/id_ed25519 \
            -o StrictHostKeyChecking=no \
            -o BatchMode=yes \
            -p "${{ vars.PROD_PORT }}" \
            "${{ vars.PROD_USER }}@${{ vars.PROD_HOST }}" \
            "echo SSH OK"

      - name: Run test deployment script
        run: |
          ssh -i ~/.ssh/id_ed25519 \
            -o BatchMode=yes \
            -p "${{ vars.PROD_PORT }}" \
            "${{ vars.PROD_USER }}@${{ vars.PROD_HOST }}" \
            "bash -lc 'cd /var/www/harheimertc.test && git fetch origin dev && git checkout -B dev origin/dev && git reset --hard origin/dev && ./deploy-test.sh'"
