# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.

# These are the steps for all CI jobs. Linux, macOS, and Windows all
# share a common set of configure/build/validate steps.  The input
# variables control all variations of the jobs.
#
# Each job validates that the proper files are installed by comparing
# the install_manifest.txt to a reference for that job. This requires
# that each job have a corresponding reference, and that thes
# references are updated when any change is made to the installation
# headers/libraries/cmake/etc.

name: CI Steps

on:
  workflow_call:
    # This inputs receive values via the "with:" section in ci_workflow.yml
    inputs:
      build:
        type: string
      os:
        type: string
      cmake:
        type: string
      cxx-standard:
        type: string
      cxx-compiler:
        type: string
      cc-compiler:
        type: string
      build-type:
        type: string
      msystem:
        type: string
      python:
        type: string
      pybind11:
        type: string
      IMATH_INSTALL_PKG_CONFIG:
        type: string
      IMATH_INSTALL_SYM_LINK:
        type: string
      BUILD_SHARED_LIBS:
        type: string
      BUILD_TESTING:
        type: string
      IMATH_BUILD_APPLE_FRAMEWORKS:
        type: string
      IMATH_TEST_PYTHON:
        type: string
      IMATH_TEST_PYBIND11:
        type: string
      namespace:
        type: string
      validate_install:
        type: string

jobs:
  steps:
    runs-on: ${{ inputs.os }}

    env:
      CXX: ${{ inputs.cxx-compiler }}
      CC: ${{ inputs.cc-compiler }}
      CMAKE: cmake

    steps:
      - name: Checkout Repository
        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

      - name: Set Up Directories & Environment
        run: |
          set -x

          # Be careful to use consistent paths between Windows and
          # Linux. Convert backslashed Windows paths to Linux style via cygpath,
          # i.e. convert D:\a\Imath\Imath to /d/a/Imath/Imath.

          # WORKSPACE is the root of the project directory
          if [[ "$RUNNER_OS" == "Windows" ]]; then
              WORKSPACE=$(cygpath -u "$GITHUB_WORKSPACE")
          else
              WORKSPACE=$GITHUB_WORKSPACE
          fi
          echo "WORKSPACE=$WORKSPACE" >> $GITHUB_ENV

          # BUILD_DIR is the CMake build directory
          BUILD_DIR=$WORKSPACE/_build
          echo "BUILD_DIR=$BUILD_DIR" >> $GITHUB_ENV

          # INSTALL_DIR is the CMake install directory
          INSTALL_DIR=$WORKSPACE/_install
          echo "INSTALL_DIR=$INSTALL_DIR" >> $GITHUB_ENV

          # IMATH_PATH is the accumulated path used for executing
          # binaries during the test steps. Note that the GH shell
          # silently and automatically adjusts the PATH variable, so
          # keep the special paths in a separate variable and assign
          # them to PATH only just prior to execution.

          IMATH_PATH=$INSTALL_DIR/bin:$INSTALL_DIR/lib
          echo "IMATH_PATH=$IMATH_PATH" >> $GITHUB_ENV

        shell: bash

      - name: Install MSYS2 ${{ inputs.msystem }}
        if: inputs.msystem != ''
        uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0
        with:
          msystem: ${{ inputs.msystem }}
          update: true
          install: git
          pacboy: cc:p cmake:p

      - name: Install python for MINGW32
        if: inputs.pybind11 == 'ON' && inputs.msystem == 'MINGW32'
        # Note that MINGW32 requires the x86 architecture
        uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
        with:
          python-version: '3.9'
          architecture: 'x86'

      - name: Install python for UCRT64
        if: inputs.pybind11 == 'ON' && inputs.msystem == 'UCRT64'
        # Note this requires the msys2 shell
        run: pacboy -S python:p pybind11:p --noconfirm
        shell: msys2 {0}

      - name: Install Python dev packages (Linux)
        if: (inputs.python == 'ON' || inputs.pybind11 == 'ON' ) && runner.os == 'Linux'
        run: |
          sudo apt-get update
          sudo apt-get install -y python3-dev
        shell: bash

      - name: Set Up Python Variables
        if: inputs.python == 'ON' || inputs.pybind11 == 'ON'
        run: |
          set -x

          # $pythonLocation is set by the setup-python step, only done for MINGW32
          if [ -n "$pythonLocation" ]; then
              PYTHON_DIR=$(cygpath -u "$pythonLocation")
              PYTHON=$PYTHON_DIR/python.exe
          else
              PYTHON=$(which python)
              PYTHON_DIR=$(dirname $PYTHON)
          fi

          echo "PYTHON=$PYTHON" >> $GITHUB_ENV

          # Add python to the path

          IMATH_PATH=$PYTHON_DIR:$IMATH_PATH
          echo "IMATH_PATH=$IMATH_PATH" >> $GITHUB_ENV

          # Install into a special directory, to confirm that the
          # manually-specified install location works properly

          PYTHON_INSTALL_DIR=$INSTALL_DIR/python
          echo "PYTHON_INSTALL_DIR=$PYTHON_INSTALL_DIR" >> $GITHUB_ENV

        shell: bash

      - name: Install pybind11
        if: inputs.pybind11 == 'ON'
        run: |
          set -x

          $PYTHON -m pip install --upgrade pip pybind11 "numpy<2"

          # Ask python for the pybind11 header directory

          pybind11_DIR=$($PYTHON -c 'import pybind11; print(pybind11.get_cmake_dir())')
          if [[ "$RUNNER_OS" == "Windows" ]]; then
              pybind11_DIR=$(cygpath -u "$pybind11_DIR")
          fi
          echo pybind11_DIR=$pybind11_DIR >> $GITHUB_ENV

        shell: bash

      - name: Set Up Conan
        if: inputs.python == 'ON'
        # conan is required for Boost.python.
        # Boost.python doesn't build under msys2, so msys2 jobs all have inputs.pyton=OFF,
        # hence the conan configuration doesn't have to support msys2
        run: |
          set -x

          CONAN_DIR=$WORKSPACE/_conan
          echo "CONAN_DIR=${CONAN_DIR}" >> $GITHUB_ENV

          conan_args=("install")
          conan_args+=("--output-folder=${CONAN_DIR}")
          conan_args+=("--build=missing")
          conan_args+=("--generator" "CMakeDeps")

          conan_args+=("--generator" "CMakeToolchain")
          conan_args+=("--settings" "build_type=${{ inputs.build-type }}")
          if [[ "${{ inputs.pybind11 }}" == "ON" ]]; then
            conan_args+=("--requires=pybind11/2.11.1")
          fi
          if [[ "${{ inputs.python }}" == "ON" ]]; then
            conan_args+=("--requires=boost/1.82.0")
            conan_args+=("--options" "boost/*:header_only=False")
            conan_args+=("--options" "boost/*:without_python=False")
            conan_args+=("--options" "boost/*:without_format=False")
            conan_args+=("--options" "boost/*:shared=True")
          fi

          python -m pip install --upgrade pip "numpy<2" conan
          conan profile detect
          conan "${conan_args[@]}"

          echo "CMAKE_TOOLCHAIN_FILE=${CONAN_DIR}/conan_toolchain.cmake" >> $GITHUB_ENV
          echo "Boost_ROOT=${CONAN_DIR}" >> $GITHUB_ENV

          if [[ "$RUNNER_OS" == "Windows" ]]; then
              CONAN_LIB=$(cygpath -u ${USERPROFILE})/.conan2/p/b
              BOOST_DLL=$(find "$CONAN_LIB" -type f -path "*/bin/boost_python*.dll" -print -quit)
              BOOST_LIB=$(dirname $BOOST_DLL)
              IMATH_PATH=$BOOST_LIB:$IMATH_PATH
              echo "IMATH_PATH=$IMATH_PATH" >> $GITHUB_ENV
          fi

        shell: bash

      - name: Install CMake
        # CMakeLists.txt specifies a minimum CMake version of 3.14 for
        # the Imath project, so use that for the CI, unless a specific
        # version is specified. The conan toolchain requires a minimum
        # of 3.15, so use that for the runs that require conan.
        run: |
          set -ex
          CMAKE=cmake
          CTEST=ctest
          if [ "${{ inputs.cmake }}" != "" ]; then
            if [ "$RUNNER_OS" == "Linux" ]; then
              CMAKE_VERSION=${{ inputs.cmake }}
              CURRENT_CMAKE_VERSION=$(cmake --version | head -n 1 | cut -f3 -d' ')
              if [ "$CMAKE_VERSION" != "$CURRENT_CMAKE_VERSION" ]; then
                wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz
                tar -xzf cmake-$CMAKE_VERSION-Linux-x86_64.tar.gz 
                CMAKE=$(find "$PWD" -type f -path "*/bin/cmake" | head -n 1)
                CTEST=$(find "$PWD" -type f -path "*/bin/ctest" | head -n 1)
              fi
            else
              echo "Explicit cmake version only supported on Linux."
              exit 1
            fi
          fi
          echo CMAKE="$CMAKE" >> $GITHUB_ENV
          echo CTEST="$CTEST" >> $GITHUB_ENV
        shell: bash

      - name: Construct CMake command
        # Construct the cmake command as a variable, so the
        # Configure step below can execute it, but also so we can store
        # in in the install_manifest as a debugging reference
        run: |
          set -x
          cmake_args=("-B" "$BUILD_DIR" "-S" "$WORKSPACE")
          cmake_args+=("-DCMAKE_INSTALL_PREFIX=$INSTALL_DIR")
          cmake_args+=("-DCMAKE_BUILD_TYPE=${{ inputs.build-type }}")
          cmake_args+=("-DCMAKE_CXX_STANDARD=${{ inputs.cxx-standard }}")
          cmake_args+=("-DBUILD_SHARED_LIBS=${{ inputs.BUILD_SHARED_LIBS }}")
          cmake_args+=("-DIMATH_INSTALL_PKG_CONFIG=${{ inputs.IMATH_INSTALL_PKG_CONFIG }}")
          cmake_args+=("-DIMATH_INSTALL_SYM_LINK=${{ inputs.IMATH_INSTALL_SYM_LINK }}")
          cmake_args+=("-DIMATH_BUILD_APPLE_FRAMEWORKS=${{ inputs.IMATH_BUILD_APPLE_FRAMEWORKS }}")
          cmake_args+=("-DBUILD_TESTING=${{ inputs.BUILD_TESTING }}")
          cmake_args+=("-DPYTHON=${{ inputs.python }}")
          cmake_args+=("-DPYBIND11=${{ inputs.pybind11 }}")
          cmake_args+=("-DCMAKE_VERBOSE_MAKEFILE=ON")
          if [ -n "${{ env.PYTHON }}" ]; then
              # make sure that CMake uses the same python installation!
              cmake_args+=("-DPython3_EXECUTABLE=${{ env.PYTHON }}")
          fi
          if [[ "${{ inputs.python }}" == "ON" || "${{ inputs.pybind11 }}" == "ON" ]]; then
              cmake_args+=("-DPYTHON_INSTALL_DIR=${{ env.PYTHON_INSTALL_DIR }}")
              cmake_args+=("-DIMATH_TEST_PYTHON=${{ inputs.IMATH_TEST_PYTHON }}")
              cmake_args+=("-DIMATH_TEST_PYBIND11=${{ inputs.IMATH_TEST_PYBIND11 }}")
          fi
          if [ -n "${{ env.pybind11_DIR }}" ]; then
              cmake_args+=("-Dpybind11_DIR=${{ env.pybind11_DIR }}")
          fi
          if [ -n "${{ env.Boost_ROOT }}" ]; then
              cmake_args+=("-DBoost_ROOT=${{ env.Boost_ROOT }}")
          fi
          if [ -n "${{ env.CMAKE_TOOLCHAIN_FILE }}" ]; then
              cmake_args+=("-DCMAKE_TOOLCHAIN_FILE=${{ env.CMAKE_TOOLCHAIN_FILE }}")
          fi
          if [[ "$RUNNER_OS" == "Windows" ]]; then
              # On Windows, Conan requires CMP0091, which controls how
              # CMAKE_MSVC_RUNTIME_LIBRARY is set
              cmake_args+=("-DCMAKE_POLICY_DEFAULT_CMP0091=NEW")
          fi
          if [ -n "${{ inputs.namespace }}" ]; then
              cmake_args+=("-DIMATH_NAMESPACE=${{ inputs.namespace }}")
              # While we're at it, simultaneously test setting the lib
              # suffix, for Imath and the python bindings, to confirm
              # that works as expected.
              cmake_args+=("-DIMATH_LIB_SUFFIX=${{ inputs.namespace }}")
              cmake_args+=("-DPYIMATH_LIB_SUFFIX=PY_${{ inputs.namespace }}")
              cmake_args+=("-DPYBINDIMATH_LIB_SUFFIX=PYBIND_${{ inputs.namespace }}")
              cmake_args+=("-DPYIMATH_OUTPUT_SUBDIR=PyImath")
              cmake_args+=("-DPYBINDIMATH_OUTPUT_SUBDIR=PyBindImath")
          fi
          if [ "${{ inputs.IMATH_BUILD_APPLE_FRAMEWORKS }}" == "ON" ]; then
              cmake_args+=("-DCMAKE_SYSTEM_NAME=iOS")
          fi

          quoted_args=$(printf '%q ' "${cmake_args[@]}")
          echo "CMAKE_ARGS=$quoted_args" >> $GITHUB_ENV

          # Set the install manifest name to include the os and build number.
          # e.g. install_manifest.macos.1.txt
          os_name=$(echo "${RUNNER_OS}" | tr '[:upper:]' '[:lower:]')  # linux, macos, windows
          build="${{ inputs.build }}"
          echo INSTALL_MANIFEST="install_manifest.${os_name}.${build}.txt" >> $GITHUB_ENV
        shell: bash

      - name: Configure & Build
        if: inputs.msystem == ''
        run: |
          set -x
          $CMAKE --version
          $CMAKE ${{ env.CMAKE_ARGS }}
          $CMAKE --build $BUILD_DIR --target install --config ${{ inputs.build-type }}
        shell: bash

      - name: Configure & Build (msys2) # requires msys2 shell
        if: inputs.msystem != ''
        # Requires msys2 shell
        run: |
          set -x
          $CMAKE --version
          $CMAKE ${{ env.CMAKE_ARGS }}
          $CMAKE --build $BUILD_DIR --target install --config ${{ inputs.build-type }}
        shell: msys2 {0}

      - name: Validate library symlinks
        if: inputs.BUILD_SHARED_LIBS == 'ON' && inputs.IMATH_BUILD_APPLE_FRAMEWORKS != 'ON' && inputs.IMATH_INSTALL_SYM_LINK == 'ON'
        # Validate that the proper symlinks have been created
        # between the various versions of the .so/.dylib/.dll,
        # especially the one created explicitly (based on the
        # IMATH_INSTALL_SYM_LINK option) with a name with no suffix.
        # Note this implicitly validates the IMATH_NAMESPACE option.
        # libImath_d.so -> libImath-3_2_d.so
        # libImath-3_2_d.so -> libImath-3_2_d.so.30
        # libImath-3_2_d.so.30.so -> libImath-3_2_d.so.30.3.2.0
        # NOTE: technically the validate_install.py script also checks this,
        # but this also confirms that the files are actually symlinks.
        run: |
          set -xe

          if [[ "${{ inputs.build-type }}" == "Debug" ]]; then
              debug_postfix="_d"
          else
              debug_postfix=""
          fi

          # ImathConfig.h holds the release version numbers
          CONFIG="$INSTALL_DIR/include/Imath/ImathConfig.h"

          NAMESPACE="${{ inputs.namespace }}"
          python_suffix=""
          if [ -z "$NAMESPACE" ] && [ -n "$PYTHON" ]; then
              python_suffix=$($PYTHON -c "import sys; print(f'_Python{sys.version_info.major}_{sys.version_info.minor}')")
          else
              PY_NAMESPACE=PY_$NAMESPACE
              PYBIND_NAMESPACE=PYBIND_$NAMESPACE
          fi

          if [[ -n "${{ inputs.msystem }}" ]]; then
              INSTALL_PREFIX=$INSTALL_DIR/bin/lib
          elif [[ "$RUNNER_OS" == "Windows" ]]; then
              INSTALL_PREFIX=$INSTALL_DIR/bin/
          else
              INSTALL_PREFIX=$INSTALL_DIR/lib/lib
          fi
          share/ci/scripts/validate_lib_symlinks.sh "${INSTALL_PREFIX}Imath$debug_postfix" "$CONFIG" "$NAMESPACE"

          if [[ "${{ inputs.python }}" == "ON" ]]; then
            share/ci/scripts/validate_lib_symlinks.sh "${INSTALL_PREFIX}PyImath$debug_postfix" "$CONFIG" "$PY_NAMESPACE" "$python_suffix"
          fi
          if [[ "${{ inputs.pybind11 }}" == "ON" ]]; then
            share/ci/scripts/validate_lib_symlinks.sh "${INSTALL_PREFIX}PyBindImath$debug_postfix" "$CONFIG" "$PYBIND_NAMESPACE" "$python_suffix"
          fi
        shell: bash

      - name: Test PyBind11 Import
        if: inputs.pybind11 == 'ON' && inputs.IMATH_TEST_PYBIND11 == 'ON' && inputs.msystem == ''
        # Test a simple "import pybindimath"
        run: |
          set -x

          # debugging code to help confirm the dlls are in the path
          #IMATH_PYD=$(cygpath -u "$PYTHON_INSTALL_DIR/pybindimath.cp39-win_amd64.pyd")
          #if [[ -f "$IMATH_PYD" ]]; then
          #    objdump -p "$IMATH_PYD" | grep 'DLL Name'
          #fi

          export PATH="$IMATH_PATH:$PATH"
          export PYTHONPATH=$PYTHON_INSTALL_DIR
          $PYTHON $WORKSPACE/src/pybind11/PyBindImathTest/test_import_pybindimath.py
        shell: bash

      - name: Test PyBind11 Import (msys2)
        if: inputs.pybind11 == 'ON' && inputs.IMATH_TEST_PYBIND11 == 'ON' && inputs.msystem != ''
        # Test a simple "import pybindimath"
        # Requires msys2 shell
        run: |
          set -x
          export PATH="$IMATH_PATH:$PATH"
          export PYTHONPATH=$PYTHON_INSTALL_DIR
          $PYTHON $WORKSPACE/src/pybind11/PyBindImathTest/test_import_pybindimath.py
        shell: msys2 {0}

      - name: Test Python Import
        if: inputs.python == 'ON' && inputs.IMATH_TEST_PYTHON == 'ON'
        # Test a simple "import imath"
        # Note that msys2 and conan don't work together, so don't even attempt "import imath" on msys2
        run: |
          set -x

          # debugging code to help confirm the dlls are in the path
          #IMATH_PYD=$(cygpath -u "$PYTHON_INSTALL_DIR/imath.pyd")
          #if [[ -f "$IMATH_PYD" ]]; then
          #    objdump -p "$IMATH_PYD" | grep 'DLL Name'
          #fi

          export PATH="$IMATH_PATH:$PATH"
          export PYTHONPATH="$PYTHON_INSTALL_DIR"
          $PYTHON "$WORKSPACE/src/python/PyImathTest/test_import_imath.py"
        shell: bash

      - name: Test
        if: inputs.BUILD_TESTING == 'ON' && inputs.msystem == ''
        run: |
          set -x
          export PATH="$IMATH_PATH:$PATH"
          export PYTHONPATH=$PYTHON_INSTALL_DIR
          $CTEST -T Test -C ${{ inputs.build-type }} --test-dir $BUILD_DIR --timeout 7200 --output-on-failure -VV
        shell: bash

      - name: Test (msys2)
        if: inputs.BUILD_TESTING == 'ON' && inputs.msystem != ''
        # Requires msys2 shell
        run: |
          set -x
          export PATH="$IMATH_PATH:$PATH"
          export PYTHONPATH=$PYTHON_INSTALL_DIR
          $CTEST -T Test -C ${{ inputs.build-type }} --test-dir $BUILD_DIR --timeout 7200 --output-on-failure -VV
        shell: msys2 {0}

      - name: Prepare install_manifest
        # Store the cmake command as the first line of the manifest,
        # and remove the path prefix, so the manifest contains only
        # the local filenames.
        run: |
          set -x
          INSTALL_MANIFEST_PATH="$BUILD_DIR/$INSTALL_MANIFEST"
          echo "# SPDX-License-Identifier: BSD-3-Clause" > $INSTALL_MANIFEST_PATH
          echo "# Copyright (c) Contributors to the OpenEXR Project." >> $INSTALL_MANIFEST_PATH
          echo "# cmake ${{ env.CMAKE_ARGS }}" >> $INSTALL_MANIFEST_PATH
          sort $BUILD_DIR/install_manifest.txt | sed -e "s:^.*/_install/::" >> $INSTALL_MANIFEST_PATH
          if [[ "$RUNNER_OS" == "Windows" ]]; then
              INSTALL_MANIFEST_PATH=$(cygpath -w $INSTALL_MANIFEST_PATH)
          fi
          echo INSTALL_MANIFEST_PATH=$INSTALL_MANIFEST_PATH >> $GITHUB_ENV
        shell: bash

      - name: Upload install_manifest.txt
        # Upload the manifest to make it possible to download for inspection and debugging
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
        with:
          name: ${{ env.INSTALL_MANIFEST }}
          path: ${{ env.INSTALL_MANIFEST_PATH }}

      - name: Validate install
        if: inputs.validate_install == 'ON'
        # Validate that the build has installed the proper files by comparing against the appropriate reference manifest
        run: |
          set -x
          $PYTHON share/ci/scripts/validate_install.py "$INSTALL_MANIFEST_PATH" "share/ci/install_manifest/$INSTALL_MANIFEST" $BUILD_DIR/CMakeCache.txt
        shell: bash

      - name: Test ImathTest Standalone
        if: inputs.msystem == '' && inputs.IMATH_BUILD_APPLE_FRAMEWORKS != 'ON'
        # Use the ImathTest program as an example of an application
        # using the Imath library,  to validate that we can build
        # against the just-installed Imath library
        run: |
          set -x
          IMATHTEST_BUILD_DIR=$WORKSPACE/_build.imathTest
          cmake_args=("-B" "$IMATHTEST_BUILD_DIR" "-S" "$WORKSPACE/src/ImathTest")
          cmake_args+=("-DCMAKE_PREFIX_PATH=$INSTALL_DIR")
          cmake_args+=("-DCMAKE_BUILD_TYPE=${{ inputs.build-type }}")
          cmake_args+=("-DCMAKE_CXX_STANDARD=${{ inputs.cxx-standard }}")
          cmake_args+=("-DCMAKE_CXX_FLAGS=${{ inputs.cxx-flags }}")
          cmake_args+=("-DCMAKE_VERBOSE_MAKEFILE=ON")
          if [[ "$RUNNER_OS" == "Windows" ]]; then
              cmake_args+=("-DCMAKE_POLICY_DEFAULT_CMP0091=NEW")
              LINK_LOG="$IMATHTEST_BUILD_DIR/ImathTest.dir/Release/ImathTest.tlog/link.command.1.tlog"
          else
              LINK_LOG="$IMATHTEST_BUILD_DIR/CMakeFiles/ImathTest.dir/link.txt"          
          fi
          if [ -n "${{ env.CMAKE_TOOLCHAIN_FILE }}" ]; then
              cmake_args+=("-DCMAKE_TOOLCHAIN_FILE=${{ env.CMAKE_TOOLCHAIN_FILE }}")
          fi
          quoted_args=$(printf '%q ' "${cmake_args[@]}")
          $CMAKE $quoted_args
          $CMAKE --build $IMATHTEST_BUILD_DIR --config ${{ inputs.build-type }}

          # Validate that there is no dependency on PyImath in the link log
          if grep -r 'PyImath' "$LINK_LOG"; then
              echo "error configuring ImathTest standalone: PyImath referenced in build artifacts"
              echo "ImathTest should not depend on PyImath"
              exit 1
          fi
          if [[ "$RUNNER_OS" == "Windows" ]]; then
              export PATH="$IMATH_PATH:$PATH"
              $IMATHTEST_BUILD_DIR/bin/"${{ inputs.build-type }}"/ImathTest.exe
          else
              $IMATHTEST_BUILD_DIR/bin/ImathTest
          fi
        shell: bash

      - name: Test ImathTest Standalone (iOS)
        if: inputs.msystem == '' && inputs.IMATH_BUILD_APPLE_FRAMEWORKS == 'ON'
        # Use the ImathTest program as an example of an application
        # using the Imath library,  to validate that we can build
        # against the just-installed Imath library
        run: |
          set -x

          IMATHTEST_BUILD_DIR=$WORKSPACE/_build.imathTest.iOS
          cmake_args=("-B" "$IMATHTEST_BUILD_DIR" "-S" "$WORKSPACE/src/ImathTest")
          cmake_args+=("-DImath_DIR=$INSTALL_DIR/lib/Imath.framework/Resources")
          cmake_args+=("-DCMAKE_BUILD_TYPE=${{ inputs.build-type }}")
          cmake_args+=("-DCMAKE_CXX_STANDARD=${{ inputs.cxx-standard }}")
          cmake_args+=("-DCMAKE_CXX_FLAGS=${{ inputs.cxx-flags }}")
          cmake_args+=("-DCMAKE_VERBOSE_MAKEFILE=ON")
          cmake_args+=("-DCMAKE_SYSTEM_NAME=iOS")
          cmake_args+=("-DCMAKE_OSX_SYSROOT=iphoneos")
          cmake_args+=("-DCMAKE_OSX_ARCHITECTURES=arm64")
          quoted_args=$(printf '%q ' "${cmake_args[@]}")
          $CMAKE $quoted_args
          $CMAKE --build $IMATHTEST_BUILD_DIR \
                --config ${{ inputs.build-type }}
          otool -L $IMATHTEST_BUILD_DIR/bin/ImathTest.app/ImathTest
        shell: bash

      - name: Test PyImathTest Standalone
        if: inputs.msystem == '' && inputs.PYTHON == 'ON' && inputs.IMATH_TEST_PYTHON == 'ON' && inputs.IMATH_BUILD_APPLE_FRAMEWORKS != 'ON'
        # Use the PyImathTestC program as an example of an application
        # that uses the PyImath library, to validate that we can build
        # against the just-installed Imath library (with python
        # bindings).
        run: |
          set -x
          PYIMATHTEST_BUILD_DIR=$WORKSPACE/_build.pyImathTest
          cmake_args=("-B" "$PYIMATHTEST_BUILD_DIR" "-S" "$WORKSPACE/src/python/PyImathTest")
          cmake_args+=("-DCMAKE_PREFIX_PATH=$INSTALL_DIR")
          cmake_args+=("-DCMAKE_BUILD_TYPE=${{ inputs.build-type }}")
          cmake_args+=("-DCMAKE_CXX_STANDARD=${{ inputs.cxx-standard }}")
          cmake_args+=("-DCMAKE_CXX_FLAGS=${{ inputs.cxx-flags }}")
          cmake_args+=("-DCMAKE_VERBOSE_MAKEFILE=ON")
          if [[ "$RUNNER_OS" == "Windows" ]]; then
              cmake_args+=("-DCMAKE_POLICY_DEFAULT_CMP0091=NEW")
          fi
          if [ -n "${{ env.Boost_ROOT }}" ]; then
              cmake_args+=("-DBoost_ROOT=${{ env.Boost_ROOT }}")
          fi
          if [ -n "${{ env.CMAKE_TOOLCHAIN_FILE }}" ]; then
              cmake_args+=("-DCMAKE_TOOLCHAIN_FILE=${{ env.CMAKE_TOOLCHAIN_FILE }}")
          fi
          quoted_args=$(printf '%q ' "${cmake_args[@]}")
          $CMAKE $quoted_args
          $CMAKE --build $PYIMATHTEST_BUILD_DIR --config ${{ inputs.build-type }}

          export PYTHONPATH=$PYTHON_INSTALL_DIR
          if [[ "$RUNNER_OS" == "Windows" ]]; then
            export PATH="$IMATH_PATH:$PATH"
            $PYIMATHTEST_BUILD_DIR/bin/"${{ inputs.build-type }}"/PyImathTestC.exe
          else
            $PYIMATHTEST_BUILD_DIR/bin/PyImathTestC
          fi
        shell: bash

      - name: Examples
        if: inputs.namespace == '' && inputs.msystem == '' && inputs.IMATH_BUILD_APPLE_FRAMEWORKS != 'ON'
        # Confirm the website examples compile and execute.
        # The example code uses the Imath:: namespace explicitly, so
        # they won't work with a custom namespace, so skip the test in
        # that case. Also don't bother with Apple Frameworks. And msys2
        # has its own step below.
        run: |
          EXAMPLES_BUILD_DIR=$WORKSPACE/_build.examples
          cmake_args=("-B" "$EXAMPLES_BUILD_DIR" "-S" "$WORKSPACE/website/examples")
          cmake_args+=("-DCMAKE_PREFIX_PATH=$INSTALL_DIR")
          cmake_args+=("-DCMAKE_BUILD_TYPE=${{ inputs.build-type }}")
          cmake_args+=("-DCMAKE_CXX_STANDARD=${{ inputs.cxx-standard }}")
          # On Windows, Conan requires CMP0091, which controls how CMAKE_MSVC_RUNTIME_LIBRARY is set
          if [[ "$RUNNER_OS" == "Windows" ]]; then
              cmake_args+=("-DCMAKE_POLICY_DEFAULT_CMP0091=NEW")
          fi
          if [ -n "${{ env.CMAKE_TOOLCHAIN_FILE }}" ]; then
              cmake_args+=("-DCMAKE_TOOLCHAIN_FILE=${{ env.CMAKE_TOOLCHAIN_FILE }}")
          fi
          quoted_args=$(printf '%q ' "${cmake_args[@]}")
          $CMAKE $quoted_args
          $CMAKE --build $EXAMPLES_BUILD_DIR --config ${{ inputs.build-type }}

          if [[ "$RUNNER_OS" == "Windows" ]]; then
            export PATH="$IMATH_PATH:$PATH"
            $EXAMPLES_BUILD_DIR/bin/"${{ inputs.build-type }}"/imath-intro.exe
            $EXAMPLES_BUILD_DIR/bin/"${{ inputs.build-type }}"/imath-examples.exe
          else
            $EXAMPLES_BUILD_DIR/bin/imath-intro
            $EXAMPLES_BUILD_DIR/bin/imath-examples
          fi
        shell: bash

      - name: Examples (msys2)
        if: inputs.namespace == '' && inputs.msystem != ''
        # Confirm the website examples compile and execute w/MINGW32 and UCRT64.
        # The example code uses the Imath:: namespace explicitly, so they
        # won't work with a custom namespace, so skip the test in that
        # case.
        run: |
          EXAMPLES_BUILD_DIR=$WORKSPACE/_build_examples
          cmake_args=("-B" "$EXAMPLES_BUILD_DIR" "-S" "$WORKSPACE/website/examples")
          cmake_args+=("-DCMAKE_PREFIX_PATH=$INSTALL_DIR")
          cmake_args+=("-DCMAKE_BUILD_TYPE=${{ inputs.build-type }}")
          cmake_args+=("-DCMAKE_CXX_STANDARD=${{ inputs.cxx-standard }}")
          # On Windows, Conan requires CMP0091, which controls how CMAKE_MSVC_RUNTIME_LIBRARY is set
          if [[ "$RUNNER_OS" == "Windows" ]]; then
              cmake_args+=("-DCMAKE_POLICY_DEFAULT_CMP0091=NEW")
          fi
          if [ -n "${{ env.CMAKE_TOOLCHAIN_FILE }}" ]; then
              cmake_args+=("-DCMAKE_TOOLCHAIN_FILE=${{ env.CMAKE_TOOLCHAIN_FILE }}")
          fi
          quoted_args=$(printf '%q ' "${cmake_args[@]}")
          $CMAKE $quoted_args
          $CMAKE --build $EXAMPLES_BUILD_DIR --config ${{ inputs.build-type }}
          export PATH="$INSTALL_DIR/bin:$PATH"
          $EXAMPLES_BUILD_DIR/bin/imath-intro.exe
          $EXAMPLES_BUILD_DIR/bin/imath-examples.exe
        shell: msys2 {0}

      - name: Test Imath.pc
        # Validate that Imath.pc works by compiling/linking the test program
        if: runner.os != 'Windows' && inputs.IMATH_INSTALL_PKG_CONFIG == 'ON' && inputs.IMATH_BUILD_APPLE_FRAMEWORKS != 'ON'
        run: |
          set -x
          share/ci/scripts/validate_pkgconfig.sh $INSTALL_DIR Imath share/ci/src/Imath.pc/Imath.pc.cpp


      - name: Test PyImath.pc
        # Validate that PyImath.pc works by compiling/linking the test program
        if: runner.os != 'Windows' && inputs.IMATH_INSTALL_PKG_CONFIG == 'ON' && inputs.PYTHON == 'ON' && inputs.IMATH_TEST_PYTHON == 'ON' && inputs.IMATH_BUILD_APPLE_FRAMEWORKS != 'ON'
        run: |
          set -x
          share/ci/scripts/validate_pkgconfig.sh $INSTALL_DIR PyImath share/ci/src/PyImath.pc/PyImath.pc.cpp
        shell: bash
