name: Build on Unix

on:
  push:
    branches:
    - main
    - cmake_integration
    paths:
    - .github/workflows/*.yml
    - '**CMakeLists.txt'
    - 'cmake/**'
    - 'examples/**'
    - 'src/**'
    - '!**Makefile'
    - '!**md'
  pull_request:
    paths:
    - .github/workflows/*.yml
    - '**CMakeLists.txt'
    - 'cmake/**'
    - 'examples/**'
    - 'src/**'
    - '!**Makefile'
    - '!**md'

permissions:
  contents: read

#env:
  # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)

defaults:
  run:
    shell: bash

jobs:

  test-install-release:
    # Use GNU compilers

    # The CMake configure and build commands are platform agnostic and should work equally
    # well on Windows or Mac.  You can convert this to a matrix build if you need
    # cross-platform coverage.
    # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
    runs-on: ${{ matrix.os }}
    timeout-minutes: 5

    env:
      BUILD_TYPE: Release
      FFLAGS: ${{ matrix.fflags }}

    strategy:
      fail-fast: true
      matrix:
        os: [ macos-latest, ubuntu-latest ]
        fflags: [
          "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -fimplicit-none -frecursive ",
          "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -fimplicit-none -frecursive -fopenmp" ]
      # Better flags but not used by now:
      #   "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all",
      #   "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all -fopenmp" ]

    steps:

    - name: Checkout SLICOT
      uses: actions/checkout@v4.2.2

    - name: Install ninja-build tool
      uses: seanmiddleditch/gha-setup-ninja@v6

    - name: Install basics (Ubuntu)
      if: ${{ matrix.os == 'ubuntu-latest' }}
      run: |
        sudo apt update
        sudo apt install -y cmake liblapack-dev libblas-dev
    - name: Install basics (MacOS)
      if: ${{ matrix.os == 'macos-latest' }}
      run: |
          brew install lapack

    - name: Use GCC-14 on MacOS
      if: ${{ matrix.os == 'macos-latest' }}
      run: >
        cmake -B build -G Ninja
        -D CMAKE_C_COMPILER="gcc-14"
        -D CMAKE_Fortran_COMPILER="gfortran-14"
        -D USE_FLAT_NAMESPACE:BOOL=ON
        -D CMAKE_PREFIX_PATH="/opt/homebrew/opt/lapack"
        -D BLA_VENDOR=Generic

    - name: Configure CMake
      # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
      # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
      run: >
        cmake -B build -G Ninja
        -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
        -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install
        -D SLICOT_TESTING:BOOL=ON
        -D BUILD_SHARED_LIBS:BOOL=ON

    - name: Build
      # Execute tests defined by the CMake configuration.
      # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
      run: cmake --build build --config ${{env.BUILD_TYPE}}

    - name: Test with OpenMP
      working-directory: ${{github.workspace}}/build
      if: ${{ contains( matrix.fflags, 'openmp' ) }}
      run: ctest -C ${{env.BUILD_TYPE}} --schedule-random -j1 --output-on-failure --timeout 100

    - name: Test
      working-directory: ${{github.workspace}}/build
      if: ${{ !contains( matrix.fflags, 'openmp' )  }}
      run: ctest -C ${{env.BUILD_TYPE}} --schedule-random -j2 --output-on-failure --timeout 100

    - name: Install
      run: cmake --build build --target install -j2

  coverage:
    runs-on: ubuntu-latest
    env:
      BUILD_TYPE: Coverage
      FFLAGS: "-fopenmp"
    steps:

    - name: Checkout SLICOT
      uses: actions/checkout@v4.2.2

    - name: Install ninja-build tool
      uses: seanmiddleditch/gha-setup-ninja@v6

    - name: Install basics
      run: |
        sudo apt update
        sudo apt install -y cmake liblapack-dev libblas-dev


    - name: Configure CMake
      # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
      # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
      run: >
        cmake -B build -G Ninja
        -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
        -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install
        -D SLICOT_BUILD_TESTING:BOOL=ON
        -D SLICOT_BUILD_SHARED_LIBS:BOOL=ON

    - name: Build
      # Execute tests defined by the CMake configuration.
      # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
      run: cmake --build build --config ${{env.BUILD_TYPE}}

    - name: Test with OpenMP
      working-directory: ${{github.workspace}}/build
      run: ctest -C ${{env.BUILD_TYPE}} --schedule-random -j1 --output-on-failure --timeout 100

    - name: Generate HTML Report
      uses: threeal/gcovr-action@v1.1.0
      with:
        html-out: coverage.html

#  memory-check:
#    runs-on: ubuntu-latest
#    env:
#      BUILD_TYPE: Debug
#
#    steps:
#
#    - name: Checkout SLICOT
#      uses: actions/checkout@v4.2.2
#
#    - name: Install ninja-build tool
#      uses: seanmiddleditch/gha-setup-ninja@v6
#
#    - name: Install APT packages
#      run: |
#        sudo apt update
#        sudo apt install -y cmake valgrind gfortran liblapack-dev libblas-dev
#
#    - name: Configure CMake
#      run: >
#        cmake -B build -G Ninja
#        -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
#        -D SLICOT_TESTING:BOOL=ON
#        -D SLICOT_BUILD_SHARED_LIBS:BOOL=ON
#
#    - name: Build
#      run: cmake --build build --config ${{env.BUILD_TYPE}}
#
#    - name: Test
#      working-directory: ${{github.workspace}}/build
#      run: |
#        ctest -C ${{env.BUILD_TYPE}} --schedule-random -j2 -T memcheck > memcheck.out
#        cat memcheck.out
#        if tail -n 1 memcheck.out | grep -q "Memory checking results:"; then
#          exit 0
#        else
#          for f in Testing/Temporary/MemoryChecker.*.log; do
#            if tail -n 1 $f | grep -q "ERROR SUMMARY: 0 errors"; then
#              tail -n 1 $f
#              continue
#            else
#              echo "Memory check failed in $f"
#              cat $f
#              exit 1
#            fi
#          done
#          exit 0
#        fi
