name: windows-build-steps
inputs:
  suite-run:
    description: Comma-separated list of test suites to run (empty to skip C++ tests)
    required: false
    default: arena_test,db_basic_test,db_test,db_etc2_test,db_merge_operand_test,bloom_test,c_test,coding_test,crc32c_test,dynamic_bloom_test,env_basic_test,env_test,hash_test,random_test
  run-java:
    description: Whether to run Java tests
    required: false
    default: "true"
runs:
  using: composite
  steps:
  - name: Detect Visual Studio generator
    id: detect_vs
    shell: pwsh
    run: |
      $ErrorActionPreference = "Stop"

      $vswhere = Join-Path ([Environment]::GetFolderPath("ProgramFilesX86")) "Microsoft Visual Studio\Installer\vswhere.exe"
      if (!(Test-Path $vswhere)) {
        throw "vswhere.exe was not found at $vswhere"
      }

      $vsInstallationsJson = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -format json -utf8
      $vsInstallations = @($vsInstallationsJson | ConvertFrom-Json)
      if ($vsInstallations.Count -eq 0) {
        throw "No Visual Studio instance with C++ tools was found."
      }

      $vsInstallation = $vsInstallations[0]
      $vsMajor = [int]$vsInstallation.catalog.productLineVersion
      if ($vsMajor -eq 0) {
        $vsMajor = [int]($vsInstallation.installationVersion.Split(".")[0])
      }

      $generatorLine = cmake --help | Where-Object {
        $_ -match "^\*?\s*Visual Studio $vsMajor\s+\d{4}\s*="
      } | Select-Object -First 1
      if (!$generatorLine) {
        throw "CMake does not support a Visual Studio generator for VS major version $vsMajor."
      }

      $cmakeGenerator = ($generatorLine -replace "^\*?\s*", "" -replace "\s*=.*$", "").Trim()
      $vsVersionRange = "[{0}.0,{1}.0)" -f $vsMajor, ($vsMajor + 1)

      echo "Detected Visual Studio at $($vsInstallation.installationPath)"
      echo "Using CMake generator: $cmakeGenerator"
      echo "Using setup-msbuild vs-version: $vsVersionRange"

      "CMAKE_GENERATOR=$cmakeGenerator" >> $env:GITHUB_ENV
      "vs_version=$vsVersionRange" >> $env:GITHUB_OUTPUT
  - name: Add msbuild to PATH
    uses: microsoft/setup-msbuild@v2
    with:
      vs-version: ${{ steps.detect_vs.outputs.vs_version }}
  - name: ccache
    uses: hendrikmuhs/ccache-action@v1.2
    with:
      max-size: "10GB"
      key: ccache-windows-${{ github.workflow }}
      restore-keys: |
        ccache-windows-
  - name: Configure ccache
    shell: pwsh
    run: |
      ccache --set-config=base_dir=C:\a\rocksdb\rocksdb
      ccache --set-config=hash_dir=false
      ccache --set-config=compiler_check=content
  - name: Custom steps
    env:
      THIRDPARTY_HOME: ${{ github.workspace }}/thirdparty
      CMAKE_HOME: C:/Program Files/CMake
      CMAKE_BIN: C:/Program Files/CMake/bin/cmake.exe
      CTEST_BIN: C:/Program Files/CMake/bin/ctest.exe
      SNAPPY_HOME: ${{ github.workspace }}/thirdparty/snappy-1.2.2
      SNAPPY_INCLUDE: ${{ github.workspace }}/thirdparty/snappy-1.2.2;${{ github.workspace }}/thirdparty/snappy-1.2.2/build
      SNAPPY_LIB_DEBUG: ${{ github.workspace }}/thirdparty/snappy-1.2.2/build/Debug/snappy.lib
    run: |-
      # NOTE: if ... Exit $LASTEXITCODE lines needed to exit and report failure
      echo ===================== Install Dependencies =====================
      if (!$env:JAVA_HOME -or !(Test-Path (Join-Path $env:JAVA_HOME "bin\javac.exe"))) {
        $javac = Get-Command javac -ErrorAction SilentlyContinue
        if (!$javac) {
          Write-Error "javac was not found on PATH and JAVA_HOME is not set."
          Exit 1
        }
        $env:JAVA_HOME = Split-Path (Split-Path $javac.Source -Parent) -Parent
      }
      echo "JAVA_HOME=$env:JAVA_HOME"
      & "$env:JAVA_HOME\bin\java.exe" -version
      & "$env:JAVA_HOME\bin\javac.exe" -version
      mkdir $Env:THIRDPARTY_HOME
      cd $Env:THIRDPARTY_HOME
      echo "Building Snappy dependency..."
      curl -Lo snappy-1.2.2.zip https://github.com/google/snappy/archive/refs/tags/1.2.2.zip
      if(!$?) { Exit $LASTEXITCODE }
      unzip -q snappy-1.2.2.zip
      if(!$?) { Exit $LASTEXITCODE }
      cd snappy-1.2.2
      mkdir build
      cd build
      & cmake -G "$Env:CMAKE_GENERATOR" .. -DSNAPPY_BUILD_TESTS=OFF -DSNAPPY_BUILD_BENCHMARKS=OFF
      if(!$?) { Exit $LASTEXITCODE }
      cmake --build . --config Debug --parallel 32 -- /p:Platform=x64
      if(!$?) { Exit $LASTEXITCODE }
      echo ======================== Build RocksDB =========================
      cd ${{ github.workspace }}
      $env:Path = "$env:JAVA_HOME\bin;" + $env:Path
      mkdir build
      cd build
      & cmake -G "$Env:CMAKE_GENERATOR" -DCMAKE_BUILD_TYPE=Debug -DWIN_CI=1 -DPORTABLE="$Env:CMAKE_PORTABLE" -DSNAPPY=1 -DXPRESS=1 -DJNI=1 ..
      if(!$?) { Exit $LASTEXITCODE }
      cd ..
      echo "Building with VS version: $Env:CMAKE_GENERATOR"
      # use more parallel processes than the number of processes available, as most of the compile command would be cache hit
      cmake --build build --config Debug --parallel 32 -- /p:LinkIncremental=false /p:Platform=x64
      if(!$?) { Exit $LASTEXITCODE }
      echo ========================= Test RocksDB =========================
      $suiteRun = "${{ inputs.suite-run }}"
      if ($suiteRun -ne "") {
        $suiteArray = $suiteRun -split ','
        build_tools\run_ci_db_test.ps1 -SuiteRun $suiteArray -Concurrency 16
        if(!$?) { Exit $LASTEXITCODE }
      } else {
        echo "Skipping C++ tests (suite-run is empty)"
      }
      if ("${{ inputs.run-java }}" -eq "true") {
        echo ======================== Test RocksJava ========================
        cd build\java
        & ctest -C Debug -j 16
        if(!$?) { Exit $LASTEXITCODE }
      } else {
        echo "Skipping Java tests"
      }
    shell: pwsh
  - name: Show ccache stats
    shell: pwsh
    run: |
      ccache --show-stats -v
