name: CI

on:
  push:
    branches:
      - main
      - master
      - develop
  pull_request:
  schedule:
    # Nightly build at 14:00 UTC, roughly midnight in Australia/Sydney.
    - cron: "0 14 * * *"
  workflow_dispatch:

jobs:
  native-windows:
    name: Native Windows Build And Tests
    runs-on: windows-2022

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Verify Visual Studio ATL
        shell: powershell
        run: |
          $atlHeaders = @(Get-ChildItem -Path "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC" -Filter atlbase.h -Recurse -ErrorAction SilentlyContinue)
          if ($atlHeaders.Count -eq 0) {
            Write-Error "Visual Studio Build Tools is missing ATL. Install the 'C++ ATL for latest v143 build tools (x86 & x64)' component, component ID Microsoft.VisualStudio.Component.VC.ATL, then restart the runner service."
            exit 1
          }
          Write-Host "Found ATL header: $($atlHeaders[0].FullName)"

      - name: Configure Debug
        shell: powershell
        run: |
          $slangRoot = "${{ vars.SLANG_ROOT }}"
          if ([string]::IsNullOrWhiteSpace($slangRoot)) {
            $slangRoot = $env:SLANG_ROOT
          }
          if ([string]::IsNullOrWhiteSpace($slangRoot)) {
            $slangRoot = Join-Path $PWD "3rdParty\slang-2026.8-windows-x86_64"
          }

          $requiredFiles = @(
            (Join-Path $slangRoot "bin\slangc.exe"),
            (Join-Path $slangRoot "bin\slang-compiler.dll"),
            (Join-Path $slangRoot "bin\slang-glslang.dll"),
            (Join-Path $slangRoot "LICENSE")
          )

          $missingFiles = @($requiredFiles | Where-Object { -not (Test-Path -LiteralPath $_) })
          if ($missingFiles.Count -gt 0) {
            Write-Error "Missing native third-party dependencies. Set Gitea repository variable SLANG_ROOT, or pre-populate the repo-local 3rdParty folder on the Windows runner. Missing: $($missingFiles -join ', ')"
            exit 1
          }

          Write-Host "Using SLANG_ROOT=$slangRoot"
          cmake --preset vs2022-x64-debug -DSLANG_ROOT="$slangRoot"

      - name: Build Debug
        shell: powershell
        run: cmake --build --preset build-debug --parallel

      - name: Run Native Tests And Shader Validation
        shell: powershell
        run: cmake --build --preset build-debug --target RUN_TESTS --parallel

  ui-ubuntu:
    name: React UI Build
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install UI Dependencies
        working-directory: ui
        run: npm ci --no-audit --no-fund

      - name: Build UI
        working-directory: ui
        run: npm run build

  package-windows:
    name: Windows Release Package
    runs-on: windows-2022
    if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
    needs:
      - native-windows
      - ui-ubuntu

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Verify Visual Studio ATL
        shell: powershell
        run: |
          $atlHeaders = @(Get-ChildItem -Path "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC" -Filter atlbase.h -Recurse -ErrorAction SilentlyContinue)
          if ($atlHeaders.Count -eq 0) {
            Write-Error "Visual Studio Build Tools is missing ATL. Install the 'C++ ATL for latest v143 build tools (x86 & x64)' component, component ID Microsoft.VisualStudio.Component.VC.ATL, then restart the runner service."
            exit 1
          }
          Write-Host "Found ATL header: $($atlHeaders[0].FullName)"

      - name: Build UI
        shell: powershell
        working-directory: ui
        run: |
          npm ci --no-audit --no-fund
          npm run build

      - name: Configure Release
        shell: powershell
        run: |
          $slangRoot = "${{ vars.SLANG_ROOT }}"
          if ([string]::IsNullOrWhiteSpace($slangRoot)) {
            $slangRoot = $env:SLANG_ROOT
          }
          if ([string]::IsNullOrWhiteSpace($slangRoot)) {
            $slangRoot = Join-Path $PWD "3rdParty\slang-2026.8-windows-x86_64"
          }

          $requiredFiles = @(
            (Join-Path $slangRoot "bin\slangc.exe"),
            (Join-Path $slangRoot "bin\slang-compiler.dll"),
            (Join-Path $slangRoot "bin\slang-glslang.dll"),
            (Join-Path $slangRoot "LICENSE")
          )

          $missingFiles = @($requiredFiles | Where-Object { -not (Test-Path -LiteralPath $_) })
          if ($missingFiles.Count -gt 0) {
            Write-Error "Missing native third-party dependencies. Set Gitea repository variable SLANG_ROOT, or pre-populate the repo-local 3rdParty folder on the Windows runner. Missing: $($missingFiles -join ', ')"
            exit 1
          }

          Write-Host "Using SLANG_ROOT=$slangRoot"
          cmake --preset vs2022-x64-release -DSLANG_ROOT="$slangRoot"

      - name: Build Release
        shell: powershell
        run: cmake --build --preset build-release --parallel

      - name: Install Runtime Package
        shell: powershell
        run: cmake --install build/vs2022-x64-release --config Release --prefix dist/VideoShader

      - name: Zip Runtime Package
        shell: powershell
        run: Compress-Archive -Path dist/VideoShader/* -DestinationPath dist/VideoShader.zip -Force

      - name: Upload Runtime Package
        # Gitea/GHES-compatible runners do not support the v4 artifact backend yet.
        uses: actions/upload-artifact@v3
        with:
          name: VideoShader-windows-release
          path: dist/VideoShader.zip
