name: e2e test windows

on:
  workflow_dispatch:
  workflow_call:
    inputs:
      scheduled:
        description: Whether this is a scheduled run.
        type: boolean
        default: false
        required: false

jobs:
  build-cli:
    name: Build Windows CLI
    runs-on: ubuntu-22.04
    permissions:
      id-token: write
      checks: write
      contents: read
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
        with:
          ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }}

      - name: Setup bazel
        uses: ./.github/actions/setup_bazel_nix

      - name: Log in to the Container registry
        uses: ./.github/actions/container_registry_login
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build CLI
        uses: ./.github/actions/build_cli
        with:
          targetOS: "windows"
          targetArch: "amd64"
          enterpriseCLI: true
          outputPath: "build/constellation"
          push: true

      - name: Upload CLI artifact
        uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
        with:
          path: build/constellation.exe
          name: "constell-exe"

  e2e-test:
    name: E2E Test Windows
    runs-on: windows-2022
    needs: build-cli
    steps:
      - name: Checkout
        uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
        with:
          ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }}

      - name: Download CLI artifact
        uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
        with:
          name: "constell-exe"

      - name: Check CLI version
        shell: pwsh
        run: |
          .\constellation.exe version
          Add-Content -Path $env:windir\System32\drivers\etc\hosts -Value "`n127.0.0.1`tlicense.confidential.cloud" -Force

      - name: Login to Azure (IAM service principal)
        uses: ./.github/actions/login_azure
        with:
          azure_credentials: ${{ secrets.AZURE_E2E_IAM_CREDENTIALS }}

      - name: Create IAM configuration
        id: iam-create
        shell: pwsh
        run: |
          $uid = Get-Random -Minimum 1000 -Maximum 9999
          $rgName = "e2e-win-${{ github.run_id }}-${{ github.run_attempt }}-$uid"
          "rgName=$($rgName)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
          .\constellation.exe config generate azure -t "workflow=${{ github.run_id }}"
          .\constellation.exe iam create azure --region=westus --resourceGroup=$rgName-rg --servicePrincipal=$rgName-sp --update-config --debug -y

      - name: Login to Azure (Cluster service principal)
        uses: ./.github/actions/login_azure
        with:
          azure_credentials: ${{ secrets.AZURE_E2E_CLUSTER_CREDENTIALS }}

      - name: Apply config
        shell: pwsh
        run: |
          .\constellation.exe apply --debug -y

      - name: Liveness probe
        shell: pwsh
        run: |
          $retryIntervalSeconds = 30
          $maxRetries = 50

          $retryCount = 0
          $allNodesReady = $false

          while (-not $allNodesReady -and $retryCount -lt $maxRetries) {
              ${retryCount}++
              Write-Host "Retry ${retryCount}: Checking node status..."

              $nodesOutput = & kubectl get nodes --kubeconfig "$PWD\constellation-admin.conf"
              $status = $?

              $nodesOutput

              if ($status) {
                  $lines = $nodesOutput -split "`r?`n" | Select-Object -Skip 1

                  if ($lines.count -eq 4) {
                      $allNodesReady = $true

                      foreach ($line in $lines) {
                          $columns = $line -split '\s+' | Where-Object { $_ -ne '' }

                          $nodeName = $columns[0]
                          $status = $columns[1]

                          if ($status -ne "Ready") {
                              Write-Host "Node $nodeName is not ready!"
                              $allNodesReady = $false
                          }
                      }
                  }
              }

              if (-not $allNodesReady -and $retryCount -lt $maxRetries) {
                  Write-Host "Retrying in $retryIntervalSeconds seconds..."
                  Start-Sleep -Seconds $retryIntervalSeconds
              }
          }

          if ($allNodesReady) {
              Write-Host "All nodes are ready!"
          }
          else {
              Write-Host "Node status check failed after $maxRetries retries."
              EXIT 1
          }

      - name: Terminate cluster
        id: terminate-cluster
        if: always()
        shell: pwsh
        run: |
          .\constellation.exe terminate --debug -y

      - name: Login to Azure (IAM service principal)
        if: always()
        uses: ./.github/actions/login_azure
        with:
          azure_credentials: ${{ secrets.AZURE_E2E_IAM_CREDENTIALS }}

      - name: Delete IAM configuration
        id: delete-iam
        if: always()
        shell: pwsh
        run: |
          .\constellation.exe iam destroy --debug -y

      - name: Clean up after failure
        # run on a cleanup failure or if cancelled
        if: (failure() && (steps.terminate-cluster.conclusion == 'failure' || steps.delete-iam.conclusion == 'failure')) || cancelled()
        shell: pwsh
        run: |
          az group delete --name ${{ steps.iam-create.outputs.rgName }}-rg --yes
          az group delete --name ${{ steps.iam-create.outputs.rgName }}-rg-identity --yes

  notify-failure:
    name: Notify about failure
    runs-on: ubuntu-22.04
    needs: e2e-test
    if: |
      failure() &&
      github.ref == 'refs/heads/main' &&
      inputs.scheduled
    steps:
      - name: Checkout
        uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
        with:
          ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }}

      - name: Setup bazel
        uses: ./.github/actions/setup_bazel_nix

      - name: Notify about failure
        continue-on-error: true
        uses: ./.github/actions/notify_e2e_failure
        with:
          projectWriteToken: ${{ secrets.PROJECT_WRITE_TOKEN }}
          test: Windows E2E Test
          provider: Azure
          attestationVariant: "azure-sev-snp"