name: Continuous Integration

on:
  push:
    branches: [ master ]
    tags: ['*']
    paths-ignore: ['**.md']
  pull_request:
    branches: [ master ]
    paths-ignore: ['**.md']
  workflow_dispatch:

jobs:
  build:
    name: ${{ matrix.config.name }}
    runs-on: ${{ matrix.config.os }}
    defaults:
      run:
        shell: ${{ matrix.config.shell }}
    strategy:
      fail-fast: false
      matrix:
        config:
          - name: Linux GCC
            os: ubuntu-24.04
            compiler: gcc
            extra-options: -DCMAKE_FIND_PACKAGE_PREFER_CONFIG=OFF
            shell: bash

          - name: macOS Clang
            os: macos-latest
            compiler: clang
            shell: bash

          - name: MSYS2 UCRT64
            os: windows-latest
            compiler: gcc
            shell: 'msys2 {0}'
            msystem: ucrt64
            msys-env: mingw-w64-ucrt-x86_64

    steps:
      - name: Install dependencies (Linux)
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install \
            ninja-build \
            libsdl2-dev \
            libsdl2-net-dev \
            libopenal-dev \
            libebur128-dev \
            libsndfile1-dev \
            libfluidsynth-dev \
            libxmp-dev

      - name: Install dependencies (macOS)
        if: runner.os == 'macOS'
        run: |
          brew install \
            ninja \
            sdl2 \
            sdl2_net \
            openal-soft \
            libebur128 \
            libsndfile \
            fluid-synth \
            libxmp \
            yyjson \
            dylibbundler

      - name: Install dependencies (MSYS2)
        if: matrix.config.shell == 'msys2 {0}'
        uses: msys2/setup-msys2@v2
        with:
          msystem: ${{ matrix.config.msystem }}
          update: false
          install: >-
            diffutils
            ${{ matrix.config.msys-env }}-python-pip
            ${{ matrix.config.msys-env }}-gcc
            ${{ matrix.config.msys-env }}-cmake
            ${{ matrix.config.msys-env }}-ninja
            ${{ matrix.config.msys-env }}-SDL2
            ${{ matrix.config.msys-env }}-SDL2_net
            ${{ matrix.config.msys-env }}-openal
            ${{ matrix.config.msys-env }}-libebur128
            ${{ matrix.config.msys-env }}-libsndfile
            ${{ matrix.config.msys-env }}-fluidsynth
            ${{ matrix.config.msys-env }}-libxmp

      - uses: actions/checkout@v4

      - name: Configure
        env:
          CC: ${{ matrix.config.compiler }}
        run: >-
          cmake -B build -G Ninja
          -DCMAKE_BUILD_TYPE=Release
          -DENABLE_WERROR=ON -DENABLE_HARDENING=ON -DENABLE_LTO=ON
          ${{ matrix.config.extra-options }}

      - name: Build
        run: cmake --build build

      - uses: actions/setup-python@v5
        with:
          python-version: '3.x'

      - name: Test
        if: github.event_name == 'workflow_dispatch'
        run: |
          cd demotest
          pip install pyyaml joblib
          python3 demotest --jobs 4 --port ../build/src/woof

      - name: Install
        run: |
          cd build
          cpack

      - name: Upload Artifacts
        if: runner.os == 'Windows'
        uses: actions/upload-artifact@v4
        with:
          name: MSYS2-UCRT64
          path: build/*.zip

  linter:
    name: ${{ matrix.name }}
    runs-on: ubuntu-24.04
    strategy:
      fail-fast: false
      matrix:
        name: [Cppcheck , Clang-Tidy]

    steps:
      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install \
            cppcheck \
            ninja-build \
            libsdl2-dev \
            libsdl2-net-dev \
            libopenal-dev \
            libebur128-dev \
            libsndfile1-dev \
            libfluidsynth-dev \
            libxmp-dev

      - uses: actions/checkout@v4

      - name: Configure
        run: >-
          cmake -B build -G Ninja
          -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
          -DCMAKE_FIND_PACKAGE_PREFER_CONFIG=OFF

      - name: Run Cppcheck
        if: ${{ matrix.name == 'Cppcheck' }}
        run: |
          mkdir cppcheck_cache
          cppcheck -j4  --cppcheck-build-dir="cppcheck_cache" \
            --quiet \
            --error-exitcode=1 \
            --check-level=exhaustive \
            --inconclusive \
            --inline-suppr \
            --std=c99 \
            --project="${{ github.workspace }}/build/compile_commands.json" \
            -i"${{ github.workspace }}/third-party" \
            -D__GNUC__

      - name: Run Clang-Tidy
        if: ${{ matrix.name == 'Clang-Tidy' }}
        uses: cpp-linter/cpp-linter-action@v2
        id: cpp-linter
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          version: 18
          step-summary: true
          files-changed-only: true
          style: ''  # disable clang-format checks.
          tidy-checks: >-
            -*
            ,clang-analyzer-*
            ,-clang-analyzer-cplusplus*
            ,-clang-analyzer-security*
            ,-clang-analyzer-valist*
          database: 'build'
          ignore: 'third-party|win32|toolsrc|src/i_pcsound.c'
