name: cmake

on:
  workflow_call:

env:
  CCACHE_DIR: ${{ github.workspace }}/.cache/ccache
  SCCACHE_DIR: ${{ github.workspace }}/.cache/sccache
  CCACHE_BASEDIR: ${{ github.workspace }}
  SCCACHE_BASEDIRS: ${{ github.workspace }}
  CCACHE_COMPILERCHECK: content
  CCACHE_MAXSIZE: 2G
  SCCACHE_CACHE_SIZE: 2G

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          # Native builds
          - os: windows-2025
            build_type: RelWithDebInfo
          - os: ubuntu-24.04
            build_type: Debug
          - os: ubuntu-24.04
            build_type: RelWithDebInfo
          - os: macos-15
            build_type: Debug
          - os: macos-15
            build_type: RelWithDebInfo
          # Cross-compile (build only; tests run on native runners)
          - os: macos-15
            build_type: RelWithDebInfo
            target_triple: x86_64-apple-darwin
            build_only: true
          - os: ubuntu-24.04
            build_type: RelWithDebInfo
            target_triple: aarch64-linux-gnu
            build_only: true
            pixi_env: cross-linux-aarch64
          - os: windows-2025
            build_type: RelWithDebInfo
            target_triple: aarch64-pc-windows-msvc
            build_only: true
            pixi_env: cross-windows-arm64
    runs-on: ${{ matrix.os }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - uses: ./.github/actions/setup-pixi
        with:
          environments: ${{ matrix.pixi_env || 'default' }}

      - name: Restore compiler cache
        uses: actions/cache@v4
        with:
          path: ${{ runner.os == 'Windows' && '.cache/sccache' || '.cache/ccache' }}
          key: ${{ runner.os }}-${{ matrix.build_type }}-${{ matrix.target_triple || 'native' }}-ccache-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.build_type }}-${{ matrix.target_triple || 'native' }}-ccache-

      - name: Zero cache stats
        run: |
          ENV="${{ matrix.pixi_env || 'default' }}"
          if [ "$RUNNER_OS" = "Windows" ]; then
            pixi run -e "$ENV" -- sccache --stop-server || true
            pixi run -e "$ENV" -- sccache --zero-stats || true
          else
            pixi run -e "$ENV" -- ccache --zero-stats || true
          fi
        shell: bash

      - name: Build (native)
        if: ${{ !matrix.target_triple }}
        run: pixi run build ${{ matrix.build_type }} ON

      - name: Build (cross-compile)
        if: ${{ matrix.target_triple }}
        shell: bash
        run: |
          ENV="${{ matrix.pixi_env || 'default' }}"
          pixi run -e "$ENV" cmake-config ${{ matrix.build_type }} OFF -- \
            "-DCLICE_TARGET_TRIPLE=${{ matrix.target_triple }}"
          pixi run -e "$ENV" cmake-build ${{ matrix.build_type }}

      - name: Upload cross-compiled binaries
        if: ${{ matrix.build_only }}
        uses: actions/upload-artifact@v4
        with:
          name: cross-build-${{ matrix.target_triple }}
          path: |
            build/${{ matrix.build_type }}/bin/
            build/${{ matrix.build_type }}/lib/
          if-no-files-found: error
          retention-days: 1

      - name: Unit tests
        if: ${{ !matrix.build_only }}
        timeout-minutes: 5
        run: pixi run unit-test ${{ matrix.build_type }}

      - name: Integration tests
        if: ${{ !matrix.build_only }}
        timeout-minutes: 20
        run: pixi run integration-test ${{ matrix.build_type }}

      - name: Smoke tests
        if: ${{ !matrix.build_only }}
        timeout-minutes: 15
        run: pixi run smoke-test ${{ matrix.build_type }}

      - name: Print cache stats and stop server
        if: always()
        run: |
          ENV="${{ matrix.pixi_env || 'default' }}"
          if [ "$RUNNER_OS" = "Windows" ]; then
            pixi run -e "$ENV" -- sccache --show-stats
            pixi run -e "$ENV" -- sccache --stop-server || true
          else
            pixi run -e "$ENV" -- ccache --show-stats
          fi
        shell: bash

  test-cross:
    needs: build
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: macos-15-intel
            build_type: RelWithDebInfo
            target_triple: x86_64-apple-darwin
          - os: ubuntu-24.04-arm
            build_type: RelWithDebInfo
            target_triple: aarch64-linux-gnu
          - os: windows-11-arm
            build_type: RelWithDebInfo
            target_triple: aarch64-pc-windows-msvc
    runs-on: ${{ matrix.os }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - uses: ./.github/actions/setup-pixi
        with:
          environments: test-run

      - name: Download cross-compiled binaries
        uses: actions/download-artifact@v4
        with:
          name: cross-build-${{ matrix.target_triple }}
          path: build/${{ matrix.build_type }}/

      - name: Make binaries executable
        if: runner.os != 'Windows'
        run: chmod +x build/${{ matrix.build_type }}/bin/*

      - name: Unit tests
        timeout-minutes: 5
        run: pixi run -e test-run unit-test ${{ matrix.build_type }}

      - name: Integration tests
        timeout-minutes: 20
        run: pixi run -e test-run integration-test ${{ matrix.build_type }}

      - name: Smoke tests
        timeout-minutes: 10
        run: pixi run -e test-run smoke-test ${{ matrix.build_type }}
