name: mcstas-basictest
on:
  push:
  pull_request:
  schedule:
    - cron: '30 23 * * 0'  # 23:30 every Sunday

  workflow_dispatch:
    inputs:
      manual-debugging:
        type: boolean
        description: Launch manual debugging tmate for inspection (automatic in case of errors)
        default: false

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          - { os: ubuntu-20.04,  CC: gcc-10,   CXX: g++-10,     python: '3.8'  }
          - { os: ubuntu-22.04,  CC: gcc,      CXX: g++,        python: '3.9'  }
          - { os: ubuntu-22.04, CC: gcc,      CXX: g++,        python: '3.10' }
          - { os: ubuntu-22.04, CC: clang,    CXX: clang++,    python: '3.11' }
          - { os: ubuntu-22.04, CC: gcc-12,   CXX: g++-12,     python: '3.11' }
          - { os: macos-12,      CC: clang,    CXX: clang++,    python: "3.11" }
          - { os: macos-13,      CC: clang,    CXX: clang++,    python: "3.11" }
          - { os: windows-latest,  CC: gcc,    CXX: g++,        python: "3.11" }

    name: ${{ matrix.os }}.${{ matrix.CC }}.python-${{ matrix.python }}
    runs-on: ${{ matrix.os }}
    env:
      CC: ${{ matrix.CC }}
      CXX: ${{ matrix.CXX }}
    defaults:
      run:
        shell: bash -el {0}

    steps:
    - name: Checkout
      uses: actions/checkout@v4
      with:
        path: src

    - name: Setup python
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python }}

    - name: Setup Bison (macOS)
      id: setup-flex-bison-macos
      if: runner.os == 'macOS'
      run: |
           brew install bison flex

    - name: Setup Bison (Windows)
      id: setup-flex-bison-Windows
      if: runner.os == 'Windows'
      run: |
           choco install winflexbison3
           pip install mslex

    - name: Setup OpenMPI (Linux)
      id: setup-openmpi-linux
      if: runner.os == 'Linux'
      run: |
           sudo apt -y install libopenmpi-dev

    - name: Setup OpenMPI (macOS-12,13)
      id: setup-openmpi-macos12
      if: runner.os == 'macOS' && matrix.os != 'macos-11'
      run: |
           brew install openmpi

    - name: Check versions
      id: version-checks
      run: |
           which python3
           python3 --version
           which cmake
           cmake --version
           #NB: bison and flex in path are actually too old, on mac we
           #inject these via a brew keg later

    - name: Configure build and install mcstas
      id: mcstas-install
      run: |
           if [ "$RUNNER_OS" == "macOS" ]; then export SDKROOT=$(xcrun --sdk macosx --show-sdk-path); fi
           set -e
           set -u
           set -x
           mkdir build_mcstas
           cd build_mcstas
           export EXTRA_ARGS_FOR_CMAKE=""
           if [ "$RUNNER_OS" == "macOS" ]; then export EXTRA_ARGS_FOR_CMAKE="-DBISON_EXECUTABLE=/usr/local/opt/bison/bin/bison -DFLEX_EXECUTABLE=/usr/local/opt/flex/bin/flex"; fi
           if [ "$RUNNER_OS" == "Linux" ]; then export EXTRA_ARGS_FOR_CMAKE="-DNEXUSLIB=/usr/lib -DNEXUSINCLUDE=/usr/include/nexus"; fi
           cmake \
               -DCMAKE_INSTALL_PREFIX=../install_mcstas \
               -S ../src \
               -G "Unix Makefiles" \
               -DMCVERSION="3.99.99" \
               -DMCCODE_BUILD_CONDA_PKG=ON \
               -DBUILD_SHARED_LIBS=ON \
               -DCMAKE_INSTALL_LIBDIR=lib \
               -DCMAKE_BUILD_TYPE=Release \
               -DBUILD_MCSTAS=ON \
               -DMCCODE_USE_LEGACY_DESTINATIONS=OFF \
               -DBUILD_TOOLS=ON \
               -DENABLE_COMPONENTS=ON \
               -DENSURE_MCPL=ON \
               -DENSURE_NCRYSTAL=OFF \
               -DENABLE_CIF2HKL=OFF \
               -DENABLE_NEUTRONICS=OFF \
               ${EXTRA_ARGS_FOR_CMAKE}
           cmake --build . --config Release
           cmake --build . --target install --config Release
           export MCSTAS_EXECUTABLE="mcstas"
           export MCRUN_EXECUTABLE="mcrun"
           if [ "$RUNNER_OS" == "Windows" ];
           then
             export MCSTAS_EXECUTABLE="mcstas.exe"
             export MCRUN_EXECUTABLE="mcrun.bat"
           fi
           test -f "../install_mcstas/bin/${MCSTAS_EXECUTABLE}"
           test -f "../install_mcstas/bin/${MCRUN_EXECUTABLE}"
           test -f "../install_mcstas/share/mcstas/tools/Python/mccodelib/__init__.py"
           test -d "../install_mcstas/share/mcstas/resources/data"
           echo *******************************************************************************
           echo Resulting mccode_config.json:
           echo *******************************************************************************
           cat ../install_mcstas/share/mcstas/tools/Python/mccodelib/mccode_config.json
           echo *******************************************************************************

    - name: Pip install various
      id: pip-install
      run: |
           set -e
           set -u
           set -x
           python3 -mpip install PyYAML ply McStasscript
           if [ "$RUNNER_OS" != "Windows" ];
           then
             python3 -mpip install ncrystal
           fi

    - name: Launch BNL_H8 instrument
      id: h8-test
      # Status: Works on Windows + Unixes
      run: |
           set -e
           set -u
           set -x
           export MCSTAS_EXECUTABLE="mcstas"
           export MCSTAS_PYGEN_EXECUTABLE="mcstas-pygen"
           export MCRUN_EXECUTABLE="mcrun"
           if [ "$RUNNER_OS" == "Windows" ];
           then
             export MCSTAS_EXECUTABLE="mcstas.exe"
             export MCSTAS_PYGEN_EXECUTABLE="mcstas-pygen.exe"
             export MCRUN_EXECUTABLE="mcrun.bat"
           fi
           test -f ./install_mcstas/bin/${MCSTAS_EXECUTABLE}
           ./install_mcstas/bin/${MCSTAS_EXECUTABLE} --version
           mkdir run_BNL_H8 && cd run_BNL_H8
           cp ../install_mcstas/share/mcstas/resources/examples/BNL/BNL_H8/BNL_H8.instr .
           ../install_mcstas/bin/${MCRUN_EXECUTABLE} BNL_H8.instr lambda=2.36
           ../install_mcstas/bin/${MCSTAS_PYGEN_EXECUTABLE} BNL_H8.instr

    - name: Launch BNL_H8 instrument (MPI)
      id: h8-test-mpi
      if: runner.os == 'Linux'  || (runner.os == 'macOS' && matrix.os != 'macos-11') # Linux or macos-12/13 only
      run: |
           set -e
           set -u
           set -x
           export MCSTAS_EXECUTABLE="mcstas"
           export MCSTAS_PYGEN_EXECUTABLE="mcstas-pygen"
           export MCRUN_EXECUTABLE="mcrun"
           test -f ./install_mcstas/bin/${MCSTAS_EXECUTABLE}
           ./install_mcstas/bin/${MCSTAS_EXECUTABLE} --version
           mkdir run_BNL_H8_mpi && cd run_BNL_H8_mpi
           cp ../install_mcstas/share/mcstas/resources/examples/BNL/BNL_H8/BNL_H8.instr .
           ../install_mcstas/bin/${MCRUN_EXECUTABLE} --mpi=2 BNL_H8.instr lambda=2.36

    - name: Launch MCPL test instrument
      id: mcpl-test
      if: runner.os == 'Linux' || runner.os == 'macOS' # Linux or macOS only
      # Status: Works on Unixes ("wrapper batches missing for Windows")
      run: |
           set -e
           set -u
           set -x
           export MCSTAS_EXECUTABLE="mcstas"
           export MCRUN_EXECUTABLE="mcrun"
           export PATH=${PATH}:${PWD}/install_mcstas/bin/:${PWD}/install_mcstas/mcstas/3.99.99/bin/
           test -f ./install_mcstas/bin/${MCSTAS_EXECUTABLE}
           ./install_mcstas/bin/${MCSTAS_EXECUTABLE} --version
           mkdir run_ESS_BEER_MCPL && cd run_ESS_BEER_MCPL
           cp ../install_mcstas/share/mcstas/resources/examples/ESS/ESS_BEER_MCPL/* .
           ../install_mcstas/bin/${MCRUN_EXECUTABLE} ESS_BEER_MCPL.instr repetition=50

    - name: Launch MCPL test instrument (mpi)
      id: mcpl-test-mpi
      if: runner.os == 'Linux'  || (runner.os == 'macOS' && matrix.os != 'macos-11') # Linux or macos-12/13 only
      # Status: Works on Unixes ("wrapper batches missing for Windows")
      run: |
           set -e
           set -u
           set -x
           export MCSTAS_EXECUTABLE="mcstas"
           export MCRUN_EXECUTABLE="mcrun"
           export PATH=${PATH}:${PWD}/install_mcstas/bin/:${PWD}/install_mcstas/mcstas/3.99.99/bin/
           test -f ./install_mcstas/bin/${MCSTAS_EXECUTABLE}
           ./install_mcstas/bin/${MCSTAS_EXECUTABLE} --version
           mkdir run_ESS_BEER_MCPL_mpi && cd run_ESS_BEER_MCPL_mpi
           cp ../install_mcstas/share/mcstas/resources/examples/ESS/ESS_BEER_MCPL/* .
            ../install_mcstas/bin/${MCRUN_EXECUTABLE} --mpi=2 ESS_BEER_MCPL.instr repetition=100

    - name: Launch NCrystal test instrument
      id: ncrystal-test
      if: runner.os == 'Linux' || runner.os == 'macOS' # Linux or macOS only
      # Status: Works on Unixes ("ncrystal missing for Windows")
      run: |
           set -e
           set -u
           set -x
           export MCSTAS_EXECUTABLE="mcstas"
           export MCRUN_EXECUTABLE="mcrun"
           export PATH=${PATH}:${PWD}/install_mcstas/bin/:${PWD}/install_mcstas/mcstas/3.99.99/bin/
           test -f ./install_mcstas/bin/${MCSTAS_EXECUTABLE}
           ./install_mcstas/bin/${MCSTAS_EXECUTABLE} --version
           mkdir run_NCrystal_example && cd run_NCrystal_example
           cp ../install_mcstas/share/mcstas/resources/examples/NCrystal/NCrystal_example/NCrystal_example.instr .
            ../install_mcstas/bin/${MCRUN_EXECUTABLE} NCrystal_example.instr sample_cfg="Y2O3_sg206_Yttrium_Oxide.ncmat\;density=0.6x"

    - name: Launch NCrystal test instrument (mpi)
      id: ncrystal-test-mpi
      if: runner.os == 'Linux' 
      # Status: Works on Unixes ("ncrystal missing for Windows")
      run: |
           set -e
           set -u
           set -x
           export MCSTAS_EXECUTABLE="mcstas"
           export MCRUN_EXECUTABLE="mcrun"
           export PATH=${PATH}:${PWD}/install_mcstas/bin/:${PWD}/install_mcstas/mcstas/3.99.99/bin/
           test -f ./install_mcstas/bin/${MCSTAS_EXECUTABLE}
           ./install_mcstas/bin/${MCSTAS_EXECUTABLE} --version
           mkdir run_NCrystal_example_mpi && cd run_NCrystal_example_mpi
           cp ../install_mcstas/share/mcstas/resources/examples/NCrystal/NCrystal_example/NCrystal_example.instr .
           clang --version
           mpirun --version
           ncrystal-config --version
           if [ "x$(uname)" == "xLinux" ]; then
               export NUM_MPI=2
           else
               export NUM_MPI=1
           fi
           ../install_mcstas/bin/${MCRUN_EXECUTABLE} --mpi=${NUM_MPI} NCrystal_example.instr sample_cfg="Y2O3_sg206_Yttrium_Oxide.ncmat\;density=0.6x"

    - name: Launch NeXus test instrument
      id: nexus-test
      if: runner.os == 'Linux' # Linux only
      # Status: Works on Linux (NeXus packages w/napi.h missing on mac+Windows)
      run: |
           set -e
           set -u
           set -x
           sudo apt-get update
           sudo apt-get -y install libnexus-dev
           export MCSTAS_EXECUTABLE="mcstas"
           export MCRUN_EXECUTABLE="mcrun"
           export PATH=${PATH}:${PWD}/install_mcstas/bin/:${PWD}/install_mcstas/mcstas/3.99.99/bin/
           if [ "x$(uname | cut -f1 -d_)" == "xMINGW64" ];
           then
             export MCSTAS_EXECUTABLE="mcstas.exe"
             export MCRUN_EXECUTABLE="mcrun.bat"
           fi
           test -f ./install_mcstas/bin/${MCSTAS_EXECUTABLE}
           ./install_mcstas/bin/${MCSTAS_EXECUTABLE} --version
           mkdir run_templateSANS_Mantid && cd run_templateSANS_Mantid
           cp ../install_mcstas/share/mcstas/resources/examples/Mantid/templateSANS_Mantid/templateSANS_Mantid.instr .
           #Not a final solution!!!:
           #if [ "x$(uname)" == "xDarwin" ]; then export MCSTAS_CC_OVERRIDE=/usr/bin/clang; fi
           if [ "x$(uname)" == "xLinux" ]; then
             ../install_mcstas/bin/${MCRUN_EXECUTABLE} --format=NeXus --IDF templateSANS_Mantid.instr lambda=6
             ../install_mcstas/bin/${MCRUN_EXECUTABLE} -c --mpi=2 --format=NeXus --IDF templateSANS_Mantid.instr lambda=6
           fi

    - name: 'Tar output files'
      id: tar-package
      if: always()
      run: |
           set -e
           set -u
           set -x
           tar cvfz mcstas-${{ matrix.os }}.${{ matrix.CC }}.python-${{ matrix.python }}_output.tgz run_*

    - name: 'Upload Artifact'
      id: tar-upload
      uses: actions/upload-artifact@v4
      if: always()
      with:
        name: mcstas-artefacts-${{ matrix.os }}.${{ matrix.CC }}.python-${{ matrix.python }}
        path: "mcstas-${{ matrix.os }}.${{ matrix.CC }}.python-${{ matrix.python }}_output.tgz"

    - name: Setup tmate session for manual debugging
      uses: mxschmitt/action-tmate@v3
      if: always() && (inputs.manual-debugging == true && steps.tar-package.outcome != 'success')
      with:
        limit-access-to-actor: true
