#--- musrview PNG integration tests -------------------------------------------

#--- these tests compare the PNG which 'musrview --png' renders. Without
#--- libASImage ROOT cannot write a PNG at all (see cmake/MusrfitCheckROOT7.cmake,
#--- which warns about it at config time), hence do not register tests which
#--- could then only fail for a reason that has nothing to do with musrfit. ---
if (NOT MUSRVIEW_HAS_IMAGE_EXPORT)
  message(STATUS "musrview_check: ROOT has no libASImage, skipping the musrview-* tests")
  return ()
endif ()

find_package(Python3 REQUIRED COMPONENTS Interpreter)

#--- musrview_check.py needs Pillow/numpy for the pixel comparison. CMake's
#--- FindPython3 picks the highest-versioned interpreter it can find on the
#--- system (Python3_FIND_STRATEGY=VERSION), which on some machines (e.g. a
#--- RHEL9 box with an extra /usr/bin/python3.14 alongside the distro's
#--- python3.9) is not the one that actually has these packages installed.
#--- Verify the interpreter CMake found; if it lacks the modules, fall back
#--- to whatever "python3" resolves to on PATH before giving up.
set(MUSRVIEW_CHECK_PYTHON3 ${Python3_EXECUTABLE})
execute_process(
  COMMAND ${MUSRVIEW_CHECK_PYTHON3} -c "import PIL, numpy"
  RESULT_VARIABLE _musrview_check_py_ok
  OUTPUT_QUIET ERROR_QUIET
)
if (_musrview_check_py_ok)
  find_program(_musrview_check_alt_python3 NAMES python3)
  if (_musrview_check_alt_python3)
    execute_process(
      COMMAND ${_musrview_check_alt_python3} -c "import PIL, numpy"
      RESULT_VARIABLE _musrview_check_alt_py_ok
      OUTPUT_QUIET ERROR_QUIET
    )
    if (NOT _musrview_check_alt_py_ok)
      message(STATUS "musrview_check: ${MUSRVIEW_CHECK_PYTHON3} lacks Pillow/numpy, "
                      "using ${_musrview_check_alt_python3} instead")
      set(MUSRVIEW_CHECK_PYTHON3 ${_musrview_check_alt_python3})
      set(_musrview_check_py_ok 0)
    endif()
  endif()
endif()
if (_musrview_check_py_ok)
  message(WARNING "musrview_check: no Python3 interpreter with Pillow/numpy found "
                   "(tried ${Python3_EXECUTABLE} and ${_musrview_check_alt_python3}); "
                   "musrview-* tests will fail at runtime. Install with "
                   "'${MUSRVIEW_CHECK_PYTHON3} -m pip install pillow numpy'.")
endif()
unset(_musrview_check_py_ok)
unset(_musrview_check_alt_py_ok)
unset(_musrview_check_alt_python3 CACHE)

#--- helper macro -------------------------------------------------------------
# add_musrview_test(test_name msr_file [extra_musrview_args...])
# msr_file is relative to ${CMAKE_SOURCE_DIR}/doc/examples.
# extra args (e.g. -f, -a) are forwarded directly to musrview.
macro(add_musrview_test test_name msr_file)
  add_test(
    NAME ${test_name}
    COMMAND ${MUSRVIEW_CHECK_PYTHON3}
      ${CMAKE_CURRENT_SOURCE_DIR}/musrview_check.py
      $<TARGET_FILE:musrview>
      ${CMAKE_SOURCE_DIR}/doc/examples/${msr_file}
      ${CMAKE_CURRENT_SOURCE_DIR}/ref
      ${test_name}
      --tol 0.03
      ${ARGN}
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/doc/examples
  )
  #--- musrview writes its PNGs next to the msr-file under a name derived from
  #--- the msr-file only (<msr>_<n>.png), hence all tests on the same msr-file
  #--- (plain, -f, -f -a) would overwrite/remove each other's PNGs under
  #--- 'ctest -j'. Serialize those, tests on different msr-files still run in
  #--- parallel.
  set_tests_properties(${test_name} PROPERTIES
    RESOURCE_LOCK ${CMAKE_SOURCE_DIR}/doc/examples/${msr_file})
endmacro()

# add_musrview_test_dir(sub_dir test_name msr_file [extra_musrview_args...])
# Like add_musrview_test(), but for msr-files whose data lives in a
# sub-directory of doc/examples; that sub-directory also becomes the working
# directory so that the relative data paths of the msr-file resolve.
macro(add_musrview_test_dir sub_dir test_name msr_file)
  add_test(
    NAME ${test_name}
    COMMAND ${MUSRVIEW_CHECK_PYTHON3}
      ${CMAKE_CURRENT_SOURCE_DIR}/musrview_check.py
      $<TARGET_FILE:musrview>
      ${CMAKE_SOURCE_DIR}/doc/examples/${sub_dir}/${msr_file}
      ${CMAKE_CURRENT_SOURCE_DIR}/ref
      ${test_name}
      --tol 0.03
      ${ARGN}
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/doc/examples/${sub_dir}
  )
  set_tests_properties(${test_name} PROPERTIES
    RESOURCE_LOCK ${CMAKE_SOURCE_DIR}/doc/examples/${sub_dir}/${msr_file})
endmacro()

#--- doc/examples tests -------------------------------------------------------

# single histogram fits
add_musrview_test(musrview-histo-MusrRoot                 test-histo-MusrRoot.msr)
add_musrview_test(musrview-histo-MusrRoot-fourier         test-histo-MusrRoot.msr       -f)
add_musrview_test(musrview-histo-MusrRoot-fourier-avg     test-histo-MusrRoot.msr       -f -a)

add_musrview_test(musrview-histo-PSI-BIN                  test-histo-PSI-BIN.msr)
add_musrview_test(musrview-histo-PSI-BIN-fourier          test-histo-PSI-BIN.msr        -f)
add_musrview_test(musrview-histo-PSI-BIN-fourier-avg      test-histo-PSI-BIN.msr        -f -a)

add_musrview_test(musrview-histo-ROOT-NPP                 test-histo-ROOT-NPP.msr)
add_musrview_test(musrview-histo-ROOT-NPP-fourier         test-histo-ROOT-NPP.msr       -f)
add_musrview_test(musrview-histo-ROOT-NPP-fourier-avg     test-histo-ROOT-NPP.msr       -f -a)

add_musrview_test(musrview-histo-HAL9500                  test-histo-HAL9500.msr)
add_musrview_test(musrview-histo-HAL9500-fourier          test-histo-HAL9500.msr        -f)
add_musrview_test(musrview-histo-HAL9500-fourier-avg      test-histo-HAL9500.msr        -f -a)

add_musrview_test(musrview-histo-HAL9500-RRF              test-histo-HAL9500-RRF.msr)
add_musrview_test(musrview-histo-HAL9500-RRF-fourier      test-histo-HAL9500-RRF.msr    -f)
add_musrview_test(musrview-histo-HAL9500-RRF-fourier-avg  test-histo-HAL9500-RRF.msr    -f -a)

add_musrview_test(musrview-histo-muMinus                  test-histo-muMinus.msr)
add_musrview_test(musrview-histo-muMinus-fourier          test-histo-muMinus.msr        -f)
add_musrview_test(musrview-histo-muMinus-fourier-avg      test-histo-muMinus.msr        -f -a)

# asymmetry fits
add_musrview_test(musrview-asy-PSI-BIN                    test-asy-PSI-BIN.msr)
add_musrview_test(musrview-asy-PSI-BIN-fourier            test-asy-PSI-BIN.msr          -f)
add_musrview_test(musrview-asy-PSI-BIN-fourier-avg        test-asy-PSI-BIN.msr          -f -a)

add_musrview_test(musrview-asy-MUD                        test-asy-MUD.msr)
add_musrview_test(musrview-asy-MUD-fourier                test-asy-MUD.msr              -f)
add_musrview_test(musrview-asy-MUD-fourier-avg            test-asy-MUD.msr              -f -a)

add_musrview_test(musrview-asy-HAL9500-RRF                test-asy-HAL9500-RRF.msr)
add_musrview_test(musrview-asy-HAL9500-RRF-fourier        test-asy-HAL9500-RRF.msr      -f)
add_musrview_test(musrview-asy-HAL9500-RRF-fourier-avg    test-asy-HAL9500-RRF.msr      -f -a)

add_musrview_test(musrview-asy-LF-BaB6                    test-asy-LF-BaB6.msr)
add_musrview_test(musrview-asy-LF-BaB6-fourier            test-asy-LF-BaB6.msr          -f)
add_musrview_test(musrview-asy-LF-BaB6-fourier-avg        test-asy-LF-BaB6.msr          -f -a)

add_musrview_test(musrview-asy-LSCO-ZF                    test-LSCO-asy-ZF.msr)
add_musrview_test(musrview-asy-LSCO-ZF-fourier            test-LSCO-asy-ZF.msr          -f)

#--- NeXus based tests. These can only work if musrfit was built with
#--- -Dnexus=1, otherwise the msr-files cannot be read at all -----------------
if (nexus)
  # the ISIS example data of this one is an HDF4 file, hence it additionally
  # needs -DHAVE_HDF4=1
  if (HAVE_HDF4)
    add_musrview_test(musrview-histo-NeXus                test-histo-NeXus.msr)
    add_musrview_test(musrview-histo-NeXus-fourier        test-histo-NeXus.msr          -f)
    add_musrview_test(musrview-histo-NeXus-fourier-avg    test-histo-NeXus.msr          -f -a)
  endif (HAVE_HDF4)

  # NeXus IDF V2 / HDF5
  add_musrview_test(musrview-histo-NeXus2                 test-histo-NeXus2.msr)
  add_musrview_test(musrview-histo-NeXus2-fourier         test-histo-NeXus2.msr         -f)
  add_musrview_test(musrview-histo-NeXus2-fourier-avg     test-histo-NeXus2.msr         -f -a)

  add_musrview_test(musrview-asy-NeXus2                   test-asy-NeXus2.msr)
  add_musrview_test(musrview-asy-NeXus2-fourier           test-asy-NeXus2.msr           -f)
  add_musrview_test(musrview-asy-NeXus2-fourier-avg       test-asy-NeXus2.msr           -f -a)
endif (nexus)

#--- doc/examples/ViewOpts tests ----------------------------------------------

add_musrview_test(musrview-asy-PSI-BIN-range                                       ViewOpts/test-asy-PSI-BIN-range.msr)
add_musrview_test(musrview-asy-PSI-BIN-range-fourier                               ViewOpts/test-asy-PSI-BIN-range.msr                               -f)
add_musrview_test(musrview-asy-PSI-BIN-range-fourier-avg                           ViewOpts/test-asy-PSI-BIN-range.msr                               -f -a)

add_musrview_test(musrview-asy-PSI-BIN-use_fit_ranges                              ViewOpts/test-asy-PSI-BIN-use_fit_ranges.msr)
add_musrview_test(musrview-asy-PSI-BIN-use_fit_ranges-fourier                      ViewOpts/test-asy-PSI-BIN-use_fit_ranges.msr                      -f)
add_musrview_test(musrview-asy-PSI-BIN-use_fit_ranges-fourier-avg                  ViewOpts/test-asy-PSI-BIN-use_fit_ranges.msr                      -f -a)

add_musrview_test(musrview-histo-PSI-BIN-no-scale-range-lc                         ViewOpts/test-histo-PSI-BIN-no-scale-range-lifetimecorrection.msr)
add_musrview_test(musrview-histo-PSI-BIN-no-scale-range-lc-fourier                 ViewOpts/test-histo-PSI-BIN-no-scale-range-lifetimecorrection.msr -f)
add_musrview_test(musrview-histo-PSI-BIN-no-scale-range-lc-fourier-avg             ViewOpts/test-histo-PSI-BIN-no-scale-range-lifetimecorrection.msr -f -a)

add_musrview_test(musrview-histo-PSI-BIN-no-scale-range-no-lc                      ViewOpts/test-histo-PSI-BIN-no-scale-range-no-lifetimecorrection.msr)
add_musrview_test(musrview-histo-PSI-BIN-no-scale-range-no-lc-fourier              ViewOpts/test-histo-PSI-BIN-no-scale-range-no-lifetimecorrection.msr -f)
add_musrview_test(musrview-histo-PSI-BIN-no-scale-range-no-lc-fourier-avg          ViewOpts/test-histo-PSI-BIN-no-scale-range-no-lifetimecorrection.msr -f -a)

add_musrview_test(musrview-histo-PSI-BIN-scale-fitRangeBin-range-lc                ViewOpts/test-histo-PSI-BIN-scale-fitRangeBin-range-lifetimecorrection.msr)
add_musrview_test(musrview-histo-PSI-BIN-scale-fitRangeBin-range-lc-fourier        ViewOpts/test-histo-PSI-BIN-scale-fitRangeBin-range-lifetimecorrection.msr -f)
add_musrview_test(musrview-histo-PSI-BIN-scale-fitRangeBin-range-lc-fourier-avg    ViewOpts/test-histo-PSI-BIN-scale-fitRangeBin-range-lifetimecorrection.msr -f -a)

add_musrview_test(musrview-histo-PSI-BIN-scale-fitRangeBin-ufr-lc                  ViewOpts/test-histo-PSI-BIN-scale-fitRangeBin-use_fit_ranges-lifetimecorrection.msr)
add_musrview_test(musrview-histo-PSI-BIN-scale-fitRangeBin-ufr-lc-fourier          ViewOpts/test-histo-PSI-BIN-scale-fitRangeBin-use_fit_ranges-lifetimecorrection.msr -f)
add_musrview_test(musrview-histo-PSI-BIN-scale-fitRangeBin-ufr-lc-fourier-avg      ViewOpts/test-histo-PSI-BIN-scale-fitRangeBin-use_fit_ranges-lifetimecorrection.msr -f -a)

add_musrview_test(musrview-histo-PSI-BIN-scale-range-lc                            ViewOpts/test-histo-PSI-BIN-scale-range-lifetimecorrection.msr)
add_musrview_test(musrview-histo-PSI-BIN-scale-range-lc-fourier                    ViewOpts/test-histo-PSI-BIN-scale-range-lifetimecorrection.msr    -f)
add_musrview_test(musrview-histo-PSI-BIN-scale-range-lc-fourier-avg                ViewOpts/test-histo-PSI-BIN-scale-range-lifetimecorrection.msr    -f -a)

add_musrview_test(musrview-histo-PSI-BIN-scale-range-no-lc                         ViewOpts/test-histo-PSI-BIN-scale-range-no-lifetimecorrection.msr)
add_musrview_test(musrview-histo-PSI-BIN-scale-range-no-lc-fourier                 ViewOpts/test-histo-PSI-BIN-scale-range-no-lifetimecorrection.msr -f)
add_musrview_test(musrview-histo-PSI-BIN-scale-range-no-lc-fourier-avg             ViewOpts/test-histo-PSI-BIN-scale-range-no-lifetimecorrection.msr -f -a)

add_musrview_test(musrview-histo-PSI-BIN-scale-sub_ranges-lc                       ViewOpts/test-histo-PSI-BIN-scale-sub_ranges-lifetimecorrection.msr)
add_musrview_test(musrview-histo-PSI-BIN-scale-sub_ranges-lc-fourier               ViewOpts/test-histo-PSI-BIN-scale-sub_ranges-lifetimecorrection.msr -f)
add_musrview_test(musrview-histo-PSI-BIN-scale-sub_ranges-lc-fourier-avg           ViewOpts/test-histo-PSI-BIN-scale-sub_ranges-lifetimecorrection.msr -f -a)

add_musrview_test(musrview-histo-PSI-BIN-scale-ufr-lc                              ViewOpts/test-histo-PSI-BIN-scale-use_fit_ranges-lifetimecorrection.msr)
add_musrview_test(musrview-histo-PSI-BIN-scale-ufr-lc-fourier                      ViewOpts/test-histo-PSI-BIN-scale-use_fit_ranges-lifetimecorrection.msr -f)
add_musrview_test(musrview-histo-PSI-BIN-scale-ufr-lc-fourier-avg                  ViewOpts/test-histo-PSI-BIN-scale-use_fit_ranges-lifetimecorrection.msr -f -a)

add_musrview_test(musrview-histo-PSI-BIN-scale-ufr-no-lc                           ViewOpts/test-histo-PSI-BIN-scale-use_fit_ranges-no-lifetimecorrection.msr)
add_musrview_test(musrview-histo-PSI-BIN-scale-ufr-no-lc-fourier                   ViewOpts/test-histo-PSI-BIN-scale-use_fit_ranges-no-lifetimecorrection.msr -f)
add_musrview_test(musrview-histo-PSI-BIN-scale-ufr-no-lc-fourier-avg               ViewOpts/test-histo-PSI-BIN-scale-use_fit_ranges-no-lifetimecorrection.msr -f -a)

#--- non-muSR plot ------------------------------------------------------------
#--- Covers the only fit type whose axis labels come from the data file rather
#--- than from the plot type. Needs the BMW user function library, hence the
#--- guard, and the freshly built library has to be findable at run time.
if (BMWlibs)
  add_musrview_test_dir(BMWlibs musrview-nonMusr-GapIntegrals test-libGapIntegrals-ASCII.msr)
  set_tests_properties(musrview-nonMusr-GapIntegrals PROPERTIES
    ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/src/external/libGapIntegrals:$ENV{LD_LIBRARY_PATH}")
endif (BMWlibs)
