# =============================================================================
# Wraith — Build & Sign Release
# =============================================================================
# Builds the Wails v3 desktop app for Windows amd64, signs it with an
# Azure Key Vault code-signing certificate via jsign, then uploads the
# signed binary and version manifest as release artifacts.
#
# Trigger: push a tag matching v* (e.g. v1.0.0) or run manually.
#
# Required secrets:
#   AZURE_TENANT_ID      — Azure AD tenant
#   AZURE_CLIENT_ID      — Service principal client ID
#   AZURE_CLIENT_SECRET   — Service principal secret
#   AZURE_KEY_VAULT_URL   — e.g. https://my-vault.vault.azure.net
#   AZURE_CERT_NAME       — Certificate/key name in the vault
#   GIT_TOKEN             — PAT for cloning private repo
# =============================================================================

name: Build & Sign Wraith

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:

jobs:
  build-and-sign:
    name: Build Windows + Sign
    runs-on: linux
    steps:
      # ---------------------------------------------------------------
      # Checkout
      # ---------------------------------------------------------------
      - name: Checkout code
        run: |
          git clone --depth 1 --branch ${{ github.ref_name }} \
            https://${{ secrets.GIT_TOKEN }}@git.command.vigilcyber.com/vigilcyber/wraith.git .

      # ---------------------------------------------------------------
      # Extract version from tag
      # ---------------------------------------------------------------
      - name: Get version from tag
        id: version
        run: |
          # Strip leading "v" from the tag (v1.2.3 -> 1.2.3)
          TAG=$(echo "${{ github.ref_name }}" | sed 's/^v//')
          echo "version=${TAG}" >> $GITHUB_OUTPUT
          echo "Building version: ${TAG}"

      # ---------------------------------------------------------------
      # Install toolchain: Go, Node, npm
      # ---------------------------------------------------------------
      - name: Install Node.js
        run: |
          # Install Node.js LTS if not present
          if ! command -v node >/dev/null 2>&1; then
            curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
            apt-get install -y -qq nodejs
          fi
          node --version
          npm --version

      # ---------------------------------------------------------------
      # Build frontend assets
      # ---------------------------------------------------------------
      - name: Build frontend
        run: |
          cd frontend
          npm ci
          npm run build
          echo "Frontend build complete:"
          ls -la dist/

      # ---------------------------------------------------------------
      # Build Windows amd64 binary
      # ---------------------------------------------------------------
      # Wails v3 cross-compilation from Linux to Windows requires CGO
      # for the webview2 bindings. Rather than pull in a full MinGW
      # cross-compiler, we build the Go binary directly — the frontend
      # assets are embedded via //go:embed in main.go, so the result is
      # a single self-contained .exe.
      # ---------------------------------------------------------------
      - name: Build wraith.exe (Windows amd64)
        run: |
          VERSION="${{ steps.version.outputs.version }}"
          echo "=== Cross-compiling wraith.exe for Windows amd64 ==="

          mkdir -p dist

          GOOS=windows GOARCH=amd64 CGO_ENABLED=0 \
            go build \
              -ldflags="-s -w -X main.version=${VERSION}" \
              -o dist/wraith.exe \
              .

          ls -la dist/wraith.exe

      # ---------------------------------------------------------------
      # Code signing — jsign + Azure Key Vault
      # ---------------------------------------------------------------
      - name: Install jsign
        run: |
          # jsign: Java-based Authenticode signing tool that runs on
          # Linux and supports Azure Key Vault as a keystore.
          JSIGN_VERSION="7.0"
          curl -sSL -o /usr/local/bin/jsign.jar \
            "https://github.com/ebourg/jsign/releases/download/${JSIGN_VERSION}/jsign-${JSIGN_VERSION}.jar"

          # Ensure a JRE is available (jsign needs Java)
          command -v java >/dev/null 2>&1 || {
            apt-get update -qq && apt-get install -y -qq default-jre-headless
          }

      - name: Get Azure Key Vault access token
        id: azure-token
        run: |
          # OAuth2 client credentials flow for Azure Key Vault access
          TOKEN=$(curl -s -X POST \
            "https://login.microsoftonline.com/${{ secrets.AZURE_TENANT_ID }}/oauth2/v2.0/token" \
            -d "client_id=${{ secrets.AZURE_CLIENT_ID }}" \
            -d "client_secret=${{ secrets.AZURE_CLIENT_SECRET }}" \
            -d "scope=https://vault.azure.net/.default" \
            -d "grant_type=client_credentials" \
            | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
          echo "::add-mask::${TOKEN}"
          echo "token=${TOKEN}" >> $GITHUB_OUTPUT

      - name: Sign wraith.exe
        run: |
          echo "=== Signing wraith.exe with Azure Key Vault certificate ==="
          java -jar /usr/local/bin/jsign.jar \
            --storetype AZUREKEYVAULT \
            --keystore "${{ secrets.AZURE_KEY_VAULT_URL }}" \
            --storepass "${{ steps.azure-token.outputs.token }}" \
            --alias "${{ secrets.AZURE_CERT_NAME }}" \
            --tsaurl http://timestamp.digicert.com \
            --tsmode RFC3161 \
            dist/wraith.exe
          echo "Signing complete."

      # ---------------------------------------------------------------
      # Version manifest
      # ---------------------------------------------------------------
      - name: Create version.json
        run: |
          VERSION="${{ steps.version.outputs.version }}"
          SHA256=$(sha256sum dist/wraith.exe | awk '{print $1}')

          cat > dist/version.json << EOF
          {
            "version": "${VERSION}",
            "filename": "wraith.exe",
            "sha256": "${SHA256}",
            "platform": "windows",
            "architecture": "amd64",
            "released": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
            "signed": true
          }
          EOF

          echo "=== version.json ==="
          cat dist/version.json

      # ---------------------------------------------------------------
      # Upload release artifacts
      # ---------------------------------------------------------------
      - name: Upload release artifacts
        run: |
          VERSION="${{ steps.version.outputs.version }}"
          ENDPOINT="https://files.command.vigilcyber.com"

          echo "=== Uploading Wraith ${VERSION} ==="

          # Versioned path
          aws s3 cp dist/ "s3://agents/wraith/${VERSION}/windows/amd64/" \
            --recursive --endpoint-url "$ENDPOINT" --no-sign-request

          # Latest path (overwritten on each release)
          aws s3 sync dist/ "s3://agents/wraith/latest/windows/amd64/" \
            --delete --endpoint-url "$ENDPOINT" --no-sign-request

          echo "=== Upload complete ==="
          echo "Versioned: ${ENDPOINT}/agents/wraith/${VERSION}/windows/amd64/"
          echo "Latest:    ${ENDPOINT}/agents/wraith/latest/windows/amd64/"
