name: Build

on:
  push:
    branches:
      - "**"
      - "!no_ci-*"
  pull_request:
    branches:
      - "**"
      - "!no_ci-*"

#
# Some repeated stuff
#
env:
  sanitizer_autotools_flags: '
    CFLAGS="-fsanitize=address,leak"
    LDFLAGS="-fsanitize=address,leak"'

  cmake_sanitizer_flags: "
    -DCMAKE_C_FLAGS=-fsanitize=address,leak
    -DCMAKE_CXX_FLAGS=-fsanitize=address,leak
    -DCMAKE_SHARED_LINKER_FLAGS=-fsanitize=address,leak"

  cmake_extra_flags: "
    -DUPNP_ENABLE_UNSPECIFIED_SERVER=ON
    -DUPNP_ENABLE_BLOCKING_TCP_CONNECTIONS=ON"

jobs:
  # Linux builds
  linux:
    name: Build (${{ matrix.os }}) - ${{ matrix.conf }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest]
        conf: [Debug, Release]
      fail-fast: false
    steps:
      - uses: actions/checkout@v6
      - name: Configure
        run: >
          cmake
          -S .
          -B build
          -DCMAKE_BUILD_TYPE=${{ matrix.conf }}
          -DBUILD_TESTING=ON
          -DDOWNLOAD_AND_BUILD_DEPS=ON
          -DUPNP_ENABLE_OPEN_SSL=ON
          -DCMAKE_C_FLAGS="-Wall -Wpedantic"
          -DCMAKE_INSTALL_PREFIX=${{ GITHUB.WORKSPACE }}/test-install
          ${{ env.cmake_extra_flags }}
      - name: Build
        run: cmake --build build --config ${{matrix.conf}}
      - name: Test
        run: |
          cd build
          ctest --output-on-failure
          cd ..
      - name: Debug output
        run: cmake -DBUILD_DIR=build -P cmake/post-test.cmake
      - name: install
        run: cmake --install build --config ${{matrix.conf}}
  omnios:
    name: Build OmniOS - ${{ matrix.conf }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest]
        conf: [Debug, Release]
      fail-fast: false
    steps:
      - uses: actions/checkout@v6
      - uses: vmactions/omnios-vm@v1
        with:
          prepare: |
            pkg install cmake gcc14 make
          run: |
            cmake \
            -S . \
            -B build \
            -DCMAKE_BUILD_TYPE=${{ matrix.conf }} \
            -DBUILD_TESTING=ON \
            -DDOWNLOAD_AND_BUILD_DEPS=ON \
            -DUPNP_ENABLE_OPEN_SSL=ON \
            -DCMAKE_C_FLAGS="-Wall -Wpedantic" \
            -DCMAKE_INSTALL_PREFIX=${{ GITHUB.WORKSPACE }}/test-install \
            ${{ env.cmake_extra_flags }}
            cmake --build build --config ${{matrix.conf}}
            cd build
            ctest --output-on-failure
            cd ..
            cmake -DBUILD_DIR=build -P cmake/post-test.cmake
            cmake --install build --config ${{matrix.conf}}
  # Windows Visual Studio builds
  windows-msvc:
    name: Build (${{ matrix.os }})  - ${{ matrix.conf }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [windows-latest, macos-latest]
        conf: [Debug, Release]
      fail-fast: false
    steps:
      - uses: actions/checkout@v6
      - name: Configure
        run: >
          cmake
          -S .
          -B build
          -DCMAKE_BUILD_TYPE=${{ matrix.conf }}
          -DBUILD_TESTING=ON
          -DDOWNLOAD_AND_BUILD_DEPS=ON
          -DCMAKE_INSTALL_PREFIX=${{ GITHUB.WORKSPACE }}/test-install
          ${{ env.cmake_extra_flags }}
      - name: Build
        run: cmake --build build --config ${{ matrix.conf }}
      - name: Test
        run: |
          cd build
          ctest --output-on-failure -C ${{ matrix.conf }}
          cd ..
      - name: Debug output
        run: cmake -DBUILD_DIR=build -P cmake/post-test.cmake
      - name: install
        run: cmake --install build --config ${{matrix.conf}}
  # Windows msys2 builds
  windows-msys2:
    name: Build MSys ${{matrix.sys}} - ${{matrix.conf}}
    runs-on: windows-latest
    strategy:
      matrix:
        sys: [mingw64, mingw32, ucrt64, clang64]
        conf: [Release, Debug]
    steps:
      - name: install sys (mingw64)
        uses: msys2/setup-msys2@v2
        if: ${{ matrix.sys == 'mingw64' }}
        with:
          msystem: ${{matrix.sys}}
          install: mingw-w64-x86_64-cmake mingw-w64-x86_64-make git mingw-w64-x86_64-gcc
      - name: install sys (mingw32)
        uses: msys2/setup-msys2@v2
        if: ${{ matrix.sys == 'mingw32' }}
        with:
          msystem: ${{matrix.sys}}
          install: mingw-w64-i686-cmake mingw-w64-i686-make git mingw-w64-i686-gcc
      - name: install sys (ucrt64)
        uses: msys2/setup-msys2@v2
        if: ${{ matrix.sys == 'ucrt64' }}
        with:
          msystem: ${{matrix.sys}}
          install: mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-make git mingw-w64-ucrt-x86_64-gcc
      - name: install sys (clang64)
        uses: msys2/setup-msys2@v2
        if: ${{ matrix.sys == 'clang64' }}
        with:
          msystem: ${{matrix.sys}}
          install: mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-make git mingw-w64-clang-x86_64-gcc
      - uses: actions/checkout@v6
      - name: Configure
        run: >
          cmake
          -S .
          -B build
          -DCMAKE_BUILD_TYPE=${{ matrix.conf }}
          -DBUILD_TESTING=ON
          -DDOWNLOAD_AND_BUILD_DEPS=ON
          -DCMAKE_INSTALL_PREFIX=${{ GITHUB.WORKSPACE }}/test-install
          ${{ env.cmake_extra_flags }}
      - name: Build
        run: cmake --build build --config ${{matrix.conf}}
      - name: Test
        run: |
          cd build
          ctest --output-on-failure -C ${{ matrix.conf }}
          cd ..
      - name: Debug output
        run: cmake -DBUILD_DIR=build -P cmake/post-test.cmake
      - name: install
        run: cmake --install build --config ${{matrix.conf}}
  # Linux sanitizer builds
  build_asan:
    name: Sanitizer build (ubuntu-latest) - ${{ matrix.tool }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        tool: [autotools, cmake]
        conf: [Debug]
    steps:
      - uses: actions/checkout@v6
      - name: bootstrap and configure (autotools)
        if: ${{ matrix.tool == 'autotools' }}
        run: >
          ./bootstrap &&
          ./configure
          --enable-debug
          ${{ env.sanitizer_autotools_flags }}
      - name: configure (cmake)
        if: ${{ matrix.tool == 'cmake' }}
        run: >
          cmake
          -S .
          -B build
          -DBUILD_TESTING=ON
          -DCMAKE_BUILD_TYPE=${{ matrix.conf }}
          -DDOWNLOAD_AND_BUILD_DEPS=ON
          -DUPNP_ENABLE_OPEN_SSL=ON
          ${{ env.cmake_sanitizer_flags }}
          ${{ env.cmake_extra_flags }}
      - name: build (autotools)
        if: ${{ matrix.tool == 'autotools' }}
        run: make
      - name: build (cmake)
        if: ${{ matrix.tool == 'cmake' }}
        run: cmake --build build
      - name: test ixml (autotools)
        if: ${{ matrix.tool == 'autotools' }}
        run: >
          cd ixml && make check ||
          (cat test-suite.log && exit 1)
      - name: test upnp (autotools)
        if: ${{ matrix.tool == 'autotools' }}
        run: >
          cd upnp && make check && cat test_init.log ||
          (cat test-suite.log test_init.log && exit 1)
      - name: ctest (cmake)
        if: ${{ matrix.tool == 'cmake' }}
        run: |
          cd build
          ctest --output-on-failure
