stages:
  - build
  - test
  - test_ngsolve
  - deploy
  - cleanup

push_github:
  stage: build
  tags:
    - linux
    - docker
    - bash
  script:
    - git remote add github git@github.com:NGSolve/netgen.git || true
    - git remote update
    - git checkout --track origin/master
    - git pull origin master
    - git push github master --tags
  only:
    - master

############################################
# Windows
############################################
.template_windows: &win
  tags:
    - windows
    - pip
  before_script:
    - |
        $ErrorActionPreference = "Stop"

        # Import MSVC environment from vcvars64.bat into the current PowerShell process
        $vcvars = '"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"'
        cmd /c "$vcvars && set" |
          ForEach-Object {
            if ($_ -match '^(.*?)=(.*)$') {
              [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])
              Set-Item -Path "env:$($matches[1])" -Value $matches[2] -ErrorAction SilentlyContinue
            }
          }

        $env:CCACHE_DIR       = "C:\tools\cache"
        $env:CI_DIR           = "C:\ci\$env:CI_PIPELINE_ID"
        $env:CCACHE_BASEDIR   = $env:CI_DIR
        $env:NETGEN_BUILD_DIR = Join-Path $env:CI_DIR "build"
        $env:INSTALL_DIR      = Join-Path $env:CI_DIR "install"
        $env:SRC_DIR          = Join-Path $env:CI_DIR "src"
        $env:NETGENDIR        = Join-Path $env:INSTALL_DIR "bin"
        $env:PYTHONPATH       = Join-Path $env:INSTALL_DIR "lib\site-packages"

        Write-Output $env:PATH
        $env:PATH = @(
          (Join-Path $env:INSTALL_DIR "bin")
          "C:\python314"
          "C:\python314\bin"
          "C:\python314\Scripts"
          "C:\tools"
          $env:PATH
        ) -join ";"
        Write-Output $env:PATH

        $env:CCACHE_HARDLINK  = "1"
        $env:CCACHE_NOHASHDIR = "1"

        & "C:\tools\ccache.exe" -s
        & "C:\tools\ccache.exe" -M "20G"

        python.exe --version
        cmake --version

build_win:
  <<: *win
  stage: build
  script:
    - |
        New-Item -ItemType Directory -Force -Path $env:SRC_DIR | Out-Null
        Get-ChildItem -Force | Copy-Item -Destination $env:SRC_DIR -Recurse -Force

        python.exe -m pip install -U netgen-occt netgen-occt-devel ninja cmake
        Set-Location $env:SRC_DIR
        git submodule update --init --recursive

        if (Test-Path $env:NETGEN_BUILD_DIR) {
          Remove-Item $env:NETGEN_BUILD_DIR -Recurse -Force
        }

        New-Item -ItemType Directory -Force -Path $env:NETGEN_BUILD_DIR | Out-Null
        Set-Location $env:NETGEN_BUILD_DIR

        cmake $env:SRC_DIR `
          -G Ninja `
          -DCMAKE_PREFIX=C:/python314 `
          -DPython3_ROOT_DIR=C:/python314 `
          -DCMAKE_INSTALL_PREFIX="$($env:INSTALL_DIR)" `
          -DCHECK_RANGE=ON `
          -DUSE_CGNS=OFF `
          -DUSE_OCC=ON `
          -DUSE_CCACHE=ON `
          -DENABLE_UNIT_TESTS=OFF `
          -DCMAKE_BUILD_TYPE=Release

        cmake --build . --target install --config Release

test_win:
  <<: *win
  stage: test
  script:
    - |
        pip install pytest-check
        Set-Location (Join-Path $env:NETGEN_BUILD_DIR "netgen")
        ctest -C Release -V --output-on-failure
        Set-Location ..
  needs: ["build_win"]

generate_results:
  <<: *win
  stage: test
  script:
    - |
        pip install pytest-check
        Set-Location "tests\pytest"
        python test_tutorials.py "new_results.json"
  needs: ["build_win"]
  when: manual
  artifacts:
    paths:
      - tests/pytest/new_results.json
    when: always
    expire_in: 1 week


cleanup_win:
  <<: *win
  stage: cleanup
  script:
    - |
        Set-Location $env:CI_PROJECT_DIR
        if (Test-Path $env:CI_DIR) {
          Remove-Item $env:CI_DIR -Recurse -Force
        }
  when: always
  allow_failure: true
  needs: ["test_win"]

############################################
# Ubuntu/Linux
############################################

.template_ubuntu: &ubuntu
  tags:
    - linux
    - bash
  before_script:
    - pwd
    - ls
    - docker info
    - export PYTHONPATH=/opt/netgen/`python3 -c "import os.path, sysconfig;print(os.path.relpath(sysconfig.get_path('platlib'), sysconfig.get_path('data')))"`
  variables:
    UBUNTU_VERSION: "22.04"

build_ubuntu_debug:
  <<: *ubuntu
  stage: build
  script:
    - docker build -t netgen_${CI_PIPELINE_ID}:${UBUNTU_VERSION} -f tests/dockerfile .
    - rm -f netgen_${CI_PIPELINE_ID}_$UBUNTU_VERSION.id
    - >-
      docker run
      --cidfile netgen_${CI_PIPELINE_ID}_${UBUNTU_VERSION}.id
      -e CCACHE_DIR=/ccache
      -e PYTHONPATH=$PYTHONPATH
      -v /mnt/ccache:/ccache
      netgen_${CI_PIPELINE_ID}:${UBUNTU_VERSION}
      bash /root/src/netgen/tests/build_debug.sh
    - docker commit `cat netgen_${CI_PIPELINE_ID}_${UBUNTU_VERSION}.id` netgen_${CI_PIPELINE_ID}_installed:${UBUNTU_VERSION}
    - rm netgen_${CI_PIPELINE_ID}_${UBUNTU_VERSION}.id

build_ubuntu_mpi:
  <<: *ubuntu
  stage: build
  script:
    - docker build -t netgen_mpi_${CI_PIPELINE_ID}:${UBUNTU_VERSION} -f tests/dockerfile_mpi .
    - rm -f netgen_mpi_${CI_PIPELINE_ID}_$UBUNTU_VERSION.id_mpi
    - >-
      docker run>-
      --cidfile netgen_mpi_${CI_PIPELINE_ID}_${UBUNTU_VERSION}.id>-
      -e CCACHE_DIR=/ccache
      -e PYTHONPATH=$PYTHONPATH
      -e RUN_SLOW_TESTS=${RUN_SLOW_TESTS}
      -v /mnt/ccache:/ccache
      netgen_mpi_${CI_PIPELINE_ID}:${UBUNTU_VERSION}
      bash /root/src/netgen/tests/build_mpi.sh
    - docker commit `cat netgen_mpi_${CI_PIPELINE_ID}_${UBUNTU_VERSION}.id` netgen_mpi_${CI_PIPELINE_ID}_installed:${UBUNTU_VERSION}
    - rm netgen_mpi_${CI_PIPELINE_ID}_${UBUNTU_VERSION}.id

test_ubuntu_debug:
  <<: *ubuntu
  stage: test
  script:
    - >-
      docker run
      -e PYTHONPATH=$PYTHONPATH
      netgen_${CI_PIPELINE_ID}_installed:${UBUNTU_VERSION}
      bash -c 'cd /root/build/netgen && make test_netgen ARGS="-V --output-on-failure"'
  needs: ["build_ubuntu_debug"]

test_ubuntu_mpi:
  <<: *ubuntu
  stage: test
  script:
    - >-
      docker run
      -e RUN_SLOW_TESTS=${RUN_SLOW_TESTS}
      -e PYTHONPATH=$PYTHONPATH
      netgen_mpi_${CI_PIPELINE_ID}_installed:${UBUNTU_VERSION}
      bash -c 'cd /root/build/netgen && make test_netgen ARGS="-V --output-on-failure"'
  needs: ["build_ubuntu_mpi"]

test_build_ngsolve:
  <<: *ubuntu
  allow_failure: true
  stage: test_ngsolve
  script:
    - >-
      docker run
      -e NETGENDIR=/opt/netgen/bin
      -e PYTHONPATH=$PYTHONPATH
      -e MKLROOT=/opt/intel/mkl
      -v /opt/intel:/opt/intel
      -e CCACHE_DIR=/ccache
      -v /mnt/ccache:/ccache
      netgen_${CI_PIPELINE_ID}_installed:${UBUNTU_VERSION}
      bash -c 'cd /root/src/netgen/tests/ && ./build_ngsolve.sh'

cleanup_ubuntu:
  stage: cleanup
  tags:
    - linux
    - bash
  script:
    # remove intermediate and old docker images and containers
    - docker rm -f `docker ps --no-trunc -aq`
    - docker images --no-trunc -aqf "dangling=true" | xargs docker rmi -f || true
    - docker rmi -f netgen_${CI_PIPELINE_ID}:${UBUNTU_VERSION} || true
    - docker rmi -f netgen_${CI_PIPELINE_ID}_installed:${UBUNTU_VERSION} || true
    - docker rmi -f netgen_mpi_${CI_PIPELINE_ID}:${UBUNTU_VERSION} || true
    - docker rmi -f netgen_mpi_${CI_PIPELINE_ID}_installed:${UBUNTU_VERSION} || true
  when: always
  allow_failure: true


############################################
# MacOSX
############################################

.template_mac: &mac
  tags:
    - macosx
    - m1
  before_script:
    - export PATH=/Library/Frameworks/Python.framework/Versions/3.14/bin:$PATH
    - export ROOT_DIR=/tmp/$CI_PIPELINE_ID
    - export SRC_DIR=$ROOT_DIR/src
    - export BUILD_DIR=$ROOT_DIR/build
    - export CMAKE_INSTALL_PREFIX=/tmp/$CI_PIPELINE_ID/install/Netgen.app
    - export PYTHONPATH=$CMAKE_INSTALL_PREFIX/Contents/Resources/`python3 -c "import os.path, sysconfig;print(os.path.relpath(sysconfig.get_path('platlib'), sysconfig.get_path('data')))"`:.
    - export PATH=$CMAKE_INSTALL_PREFIX/Contents/MacOS:$PATH

build_mac:
  <<: *mac
  stage: build
  script:
    - python3 -m pip install -U netgen-occt netgen-occt-devel cmake pytest-check
    - git submodule update --init --recursive
    - rm -rf $BUILD_DIR
    - mkdir -p $BUILD_DIR
    - rm -rf $SRC_DIR
    - mkdir -p $SRC_DIR
    - cp -a . $SRC_DIR/
    - cd $BUILD_DIR
    - >-
        cmake $SRC_DIR
        -DCMAKE_INSTALL_PREFIX=$CMAKE_INSTALL_PREFIX
        -DCMAKE_BUILD_TYPE=Release
        -DCHECK_RANGE=ON
        -DUSE_NATIVE_ARCH=ON
        -DUSE_CCACHE=ON
        -DENABLE_UNIT_TESTS=ON
        -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15
        -DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
        -DUSE_CGNS=OFF
        -DPython3_ROOT_DIR=/Library/Frameworks/Python.framework/Versions/3.14
        -DUSE_OCC=ON
    - make -j5 install

test_mac:
  <<: *mac
  stage: test
  script:
    - cd $BUILD_DIR/netgen
    - ctest . -V --output-on-failure
  needs: ["build_mac"]

cleanup_mac:
  <<: *mac
  stage: cleanup
  script:
    - rm -rf $ROOT_DIR
  when: always
  allow_failure: true
  needs: ["test_mac"]

pip_linux:
  image: quay.io/pypa/manylinux_2_28_x86_64
  stage: build
  tags:
    - pip
    - linux
    - docker
  script:
    - ./tests/build_pip.sh
  when: manual

pip_windows:
  stage: build
  tags:
    - pip
    - windows
  script:
    - .\tests\build_pip.ps1 C:\Python314
    - .\tests\build_pip.ps1 C:\Python313
    - .\tests\build_pip.ps1 C:\Python312
    - .\tests\build_pip.ps1 C:\Python311
    - .\tests\build_pip.ps1 C:\Python310
  when: manual

pip_macos:
  stage: build
  tags:
    - pip
    - macosx
    - m1
  script:
    - ./tests/build_pip_mac.sh 3.14
    - ./tests/build_pip_mac.sh 3.13
    - ./tests/build_pip_mac.sh 3.12
    - ./tests/build_pip_mac.sh 3.11
    - ./tests/build_pip_mac.sh 3.10
  when: manual
