name: CI
on:
  push:
  pull_request:

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt
      - name: Install system dependencies
        if: matrix.os == 'ubuntu-latest'
        run: sudo apt-get update && sudo apt-get install -y libdrm-dev libdrm-amdgpu1
      - name: Cargo fmt
        run: cargo fmt --all -- --check
      - name: Clippy
        run: cargo clippy --all-targets --all-features -- -D warnings
      - name: Build (release)
        run: cargo build --release --workspace
      - name: Start agent (Ubuntu)
        if: matrix.os == 'ubuntu-latest'
        shell: bash
        run: |
          set -euo pipefail
          # Use debug build for faster startup in CI
          RUST_LOG=info cargo run -p socktop_agent -- -p 3000 &
          AGENT_PID=$!
          echo "AGENT_PID=$AGENT_PID" >> $GITHUB_ENV
          # Wait for port 3000 to accept connections (30s max)
          for i in {1..60}; do
            if bash -lc "</dev/tcp/127.0.0.1/3000" &>/dev/null; then
              echo "agent is ready"
              break
            fi
            sleep 0.5
          done
      - name: Run WS probe test (Ubuntu)
        if: matrix.os == 'ubuntu-latest'
        shell: bash
        env:
          SOCKTOP_WS: ws://127.0.0.1:3000/ws
        run: |
          set -euo pipefail
          cargo test -p socktop --test ws_probe -- --nocapture
      - name: Stop agent (Ubuntu)
        if: always() && matrix.os == 'ubuntu-latest'
        shell: bash
        run: |
          if [ -n "${AGENT_PID:-}" ]; then kill $AGENT_PID || true; fi
      - name: Start agent (Windows)
        if: matrix.os == 'windows-latest'
        shell: pwsh
        run: |
          $p = Start-Process -FilePath "cargo" -ArgumentList "run -p socktop_agent -- -p 3000" -PassThru
          echo "AGENT_PID=$($p.Id)" | Out-File -FilePath $env:GITHUB_ENV -Append
          $ready = $false
          for ($i = 0; $i -lt 60; $i++) {
            if (Test-NetConnection -ComputerName 127.0.0.1 -Port 3000 -InformationLevel Quiet) { $ready = $true; break }
            Start-Sleep -Milliseconds 500
          }
          if (-not $ready) { Write-Error "agent did not become ready" }
      - name: Run WS probe test (Windows)
        if: matrix.os == 'windows-latest'
        shell: pwsh
        run: |
          $env:SOCKTOP_WS = "ws://127.0.0.1:3000/ws"
          cargo test -p socktop --test ws_probe -- --nocapture
      - name: Stop agent (Windows)
        if: always() && matrix.os == 'windows-latest'
        shell: pwsh
        run: |
          if ($env:AGENT_PID) { Stop-Process -Id $env:AGENT_PID -Force -ErrorAction SilentlyContinue }
      - name: Smoke test (client --help)
        run: cargo run -p socktop -- --help
      - name: Package artifacts
        shell: bash
        run: |
          set -e
          mkdir dist
          if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
            cp target/release/socktop.exe dist/
            cp target/release/socktop_agent.exe dist/
            7z a socktop-${{ matrix.os }}.zip dist/*
          else
            cp target/release/socktop dist/
            cp target/release/socktop_agent dist/
            tar czf socktop-${{ matrix.os }}.tar.gz -C dist .
          fi
      - name: Upload build artifacts (ephemeral)
        uses: actions/upload-artifact@v4
        with:
          name: socktop-${{ matrix.os }}
          path: |
            *.tar.gz
            *.zip
      - name: Upload to rolling GitHub Release (main only)
        if: github.ref == 'refs/heads/main' && github.event_name == 'push'
        uses: softprops/action-gh-release@v2
        with:
          tag_name: latest
          name: Latest build
          prerelease: true
          draft: false
          files: |
            *.tar.gz
            *.zip
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
