name: CI

on:
  push:
  pull_request:

jobs:
  build-test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [warp-ubuntu-latest-x64-16x, warp-macos-15-arm64-12x, warp-windows-latest-x64-16x]
    env:
      CMAKE_BUILD_TYPE: Release
      # Enable OFX integration tests that require external plugin bundles
      RUN_OFX_ITEST: "1"
      # Enable plugin subsystem smoke tests
      OAK_PLUGIN_SMOKE_TEST: "1"

    steps:
      - uses: actions/checkout@v4
        with:
          submodules: 'true'

      # ------------------------------------------------------------------
      # Linux dependencies
      # ------------------------------------------------------------------
      - name: Install dependencies (Linux)
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install -y \
            ninja-build pkg-config nasm \
            qt6-base-dev qt6-base-dev-tools qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
            libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libavfilter-dev \
            libopencolorio-dev libopenimageio-dev libopenexr-dev libexpat1-dev \
            portaudio19-dev libgl1-mesa-dev libxkbcommon-dev

      # ------------------------------------------------------------------
      # macOS dependencies
      # ------------------------------------------------------------------
      - name: Install dependencies (macOS)
        if: runner.os == 'macOS'
        run: |
          brew update
          brew install ninja pkg-config qt@6 ffmpeg openimageio opencolorio openexr portaudio expat molten-vk vulkan-headers
          echo "$(brew --prefix qt@6)/bin" >> "$GITHUB_PATH"
          echo "CMAKE_PREFIX_PATH=$(brew --prefix qt@6)" >> "$GITHUB_ENV"

      - name: Build OpenTimelineIO (macOS)
        if: runner.os == 'macOS'
        run: |
          git clone --depth 1 --branch v0.16.0 https://github.com/PixarAnimationStudios/OpenTimelineIO.git
          cmake -S OpenTimelineIO -B OpenTimelineIO/build -G Ninja \
            -DOTIO_SHARED_LIBS=ON \
            -DOTIO_PYTHON_BINDINGS=OFF \
            -DCMAKE_BUILD_TYPE=Release \
            -DCMAKE_INSTALL_PREFIX="${PWD}/otio-install"
          cmake --build OpenTimelineIO/build
          cmake --install OpenTimelineIO/build
          echo "OTIO_LOCATION=${PWD}/otio-install" >> "$GITHUB_ENV"

      # ------------------------------------------------------------------
      # Windows dependencies (MSYS2)
      # ------------------------------------------------------------------
      - name: Setup MSYS2
        if: runner.os == 'Windows'
        uses: msys2/setup-msys2@v2
        with:
          msystem: UCRT64
          update: true
          cache: true
          install: >-
            mingw-w64-ucrt-x86_64-cmake
            mingw-w64-ucrt-x86_64-ninja
            mingw-w64-ucrt-x86_64-gcc
            mingw-w64-ucrt-x86_64-qt6-base
            mingw-w64-ucrt-x86_64-qt6-tools
            mingw-w64-ucrt-x86_64-ffmpeg
            mingw-w64-ucrt-x86_64-openimageio
            mingw-w64-ucrt-x86_64-opencolorio
            mingw-w64-ucrt-x86_64-openexr
            mingw-w64-ucrt-x86_64-fmt
            mingw-w64-ucrt-x86_64-expat
            mingw-w64-ucrt-x86_64-portaudio
            mingw-w64-ucrt-x86_64-vulkan-headers
            mingw-w64-ucrt-x86_64-vulkan-loader
            mingw-w64-ucrt-x86_64-make

      # ------------------------------------------------------------------
      # Configure
      # ------------------------------------------------------------------
      - name: Configure (Linux)
        if: runner.os == 'Linux'
        run: |
          cmake -S . -B build -G Ninja \
            -DBUILD_TESTS=ON \
            -DBUILD_QT6=ON \
            -DCMAKE_DISABLE_FIND_PACKAGE_Vulkan=ON \
            -DOCIO_LOCATION=/usr \
            -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}

      - name: Configure (macOS)
        if: runner.os == 'macOS'
        run: |
          cmake -S . -B build -G Ninja \
            -DBUILD_TESTS=ON \
            -DBUILD_QT6=ON \
            -DOCIO_LOCATION=$(brew --prefix opencolorio) \
            -DOTIO_LOCATION=${OTIO_LOCATION} \
            -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}

      - name: Configure (Windows)
        if: runner.os == 'Windows'
        shell: msys2 {0}
        run: |
          cmake -S . -B build -G Ninja \
            -DBUILD_TESTS=ON \
            -DBUILD_QT6=ON \
            -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}

      # ------------------------------------------------------------------
      # Build Oak
      # ------------------------------------------------------------------
      - name: Build
        if: runner.os != 'Windows'
        run: cmake --build build --config ${{ env.CMAKE_BUILD_TYPE }}

      - name: Build (Windows)
        if: runner.os == 'Windows'
        shell: msys2 {0}
        run: cmake --build build --config ${{ env.CMAKE_BUILD_TYPE }}

      # ------------------------------------------------------------------
      # Clone and build OpenFX-Misc plugins (used by OFX integration tests)
      # ------------------------------------------------------------------
      - name: Clone OpenFX-Misc
        run: git clone --recursive --depth 1 https://github.com/NatronGitHub/openfx-misc.git

      - name: Build OpenFX-Misc plugins (Unix)
        if: runner.os != 'Windows'
        run: |
          cd openfx-misc
          make -j16
          sudo make install
          PLUGIN_FILE=$(find /usr/OFX/Plugins /usr/local/OFX/Plugins . -name "*.ofx.bundle" -print -quit 2>/dev/null | head -1)
          if [ -n "$PLUGIN_FILE" ]; then
            PLUGIN_DIR=$(dirname "$PLUGIN_FILE")
          else
            PLUGIN_DIR="$PWD"
          fi
          echo "OAK_OFX_ITEST=1" >> "$GITHUB_ENV"
          echo "OAK_OFX_PLUGIN_PATH=$PLUGIN_DIR" >> "$GITHUB_ENV"
          echo "OAK_OFX_PLUGIN_ID=net.sf.openfx.ChromaKeyerPlugin" >> "$GITHUB_ENV"

      # ------------------------------------------------------------------
      # Run all tests (including previously environment-gated OFX tests)
      # ------------------------------------------------------------------
      - name: Test (Linux)
        if: runner.os == 'Linux'
        env:
          QT_QPA_PLATFORM: offscreen
        run: ctest --test-dir build --output-on-failure -C ${{ env.CMAKE_BUILD_TYPE }}

      - name: Test (macOS)
        if: runner.os == 'macOS'
        run: ctest --test-dir build --output-on-failure -C ${{ env.CMAKE_BUILD_TYPE }}

      - name: Test (Windows)
        if: runner.os == 'Windows'
        shell: msys2 {0}
        run: ctest --test-dir build --output-on-failure -C ${{ env.CMAKE_BUILD_TYPE }}

      # ------------------------------------------------------------------
      # Filtered gtest runs for clearer CI output
      # ------------------------------------------------------------------
      - name: Plugin Smoke Tests (Linux)
        if: runner.os == 'Linux'
        env:
          QT_QPA_PLATFORM: offscreen
        run: ./build/tests/gtest/olive-gtest --gtest_filter="PluginSmoke*"

      - name: Plugin Smoke Tests (macOS)
        if: runner.os == 'macOS'
        run: ./build/tests/gtest/olive-gtest --gtest_filter="PluginSmoke*"

      - name: Plugin Smoke Tests (Windows)
        if: runner.os == 'Windows'
        shell: msys2 {0}
        run: ./build/tests/gtest/olive-gtest --gtest_filter="PluginSmoke*"

      - name: OFX Integration Tests (Linux)
        if: runner.os == 'Linux'
        env:
          QT_QPA_PLATFORM: offscreen
        run: ./build/tests/gtest/olive-gtest --gtest_filter="PluginIntegration.*:PluginMisc.*"

      - name: OFX Integration Tests (macOS)
        if: runner.os == 'macOS'
        run: ./build/tests/gtest/olive-gtest --gtest_filter="PluginIntegration.*:PluginMisc.*"

      - name: Audio Smoke Tests (Linux)
        if: runner.os == 'Linux'
        env:
          QT_QPA_PLATFORM: offscreen
        run: ./build/tests/gtest/olive-gtest --gtest_filter="AudioSmoke*"

      - name: Audio Smoke Tests (macOS)
        if: runner.os == 'macOS'
        run: ./build/tests/gtest/olive-gtest --gtest_filter="AudioSmoke*"

      - name: Audio Smoke Tests (Windows)
        if: runner.os == 'Windows'
        shell: msys2 {0}
        run: ./build/tests/gtest/olive-gtest --gtest_filter="AudioSmoke*"

      - name: Viewer Smoke Tests (Linux)
        if: runner.os == 'Linux'
        env:
          QT_QPA_PLATFORM: offscreen
        run: ./build/tests/gtest/olive-gtest --gtest_filter="ViewerSmoke*"

      - name: Viewer Smoke Tests (macOS)
        if: runner.os == 'macOS'
        run: ./build/tests/gtest/olive-gtest --gtest_filter="ViewerSmoke*"

      - name: Viewer Smoke Tests (Windows)
        if: runner.os == 'Windows'
        shell: msys2 {0}
        run: ./build/tests/gtest/olive-gtest --gtest_filter="ViewerSmoke*"

  # ------------------------------------------------------------------
  # Experimental dynamic render backend (Linux only)
  # ------------------------------------------------------------------
  build-test-dynamic-backend:
    runs-on: warp-ubuntu-latest-x64-16x
    env:
      CMAKE_BUILD_TYPE: Release
      QT_QPA_PLATFORM: offscreen

    steps:
      - uses: actions/checkout@v4
        with:
          submodules: 'true'

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y \
            ninja-build pkg-config nasm \
            qt6-base-dev qt6-base-dev-tools qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
            libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev libavfilter-dev \
            libopencolorio-dev libopenimageio-dev libopenexr-dev libexpat1-dev \
            portaudio19-dev libgl1-mesa-dev libxkbcommon-dev

      - name: Configure
        run: |
          cmake -S . -B build -G Ninja \
            -DBUILD_TESTS=ON \
            -DBUILD_QT6=ON \
            -DOAK_ENABLE_DYNAMIC_RENDER_BACKEND=ON \
            -DCMAKE_DISABLE_FIND_PACKAGE_Vulkan=ON \
            -DOCIO_LOCATION=/usr \
            -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}

      - name: Build
        run: cmake --build build --config ${{ env.CMAKE_BUILD_TYPE }}

      - name: Test
        run: ctest --test-dir build --output-on-failure -C ${{ env.CMAKE_BUILD_TYPE }}

      - name: Dynamic Render Backend Smoke Tests
        run: ./build/tests/gtest/olive-gtest --gtest_filter="DynamicRenderBackend*"
