cmake_minimum_required(VERSION 3.17)

#
#  Sample project to test compatibility of different versions of libpsml
#  (while final API extensions (e.g. procedure pointers and 'stat' optional
#   argument) and CMake options solidify)
#
#  Extra options in the Cmake configuration invocation:
#
#  -  Modern versions of libpsml are able to recover the xmlf90
#     dependency information using variables recorded in the cmake "config" file.
#     If your version of libpsml is old, or you want to "pre-find" xmlf90 before
#     looking for libpsml, use the flag:
#
#     -DPSML_OLD_CONFIG=TRUE
#
#  -  To work around bug in shared library linking
#     in versions of libpsml without procedure pointers
#
#     -DPSML_FIX_DIE_ISSUE=TRUE
#
#

project(
  test_psml
  VERSION 0.1.0
  LANGUAGES Fortran
  )


if (PSML_OLD_CONFIG)
  find_package(xmlf90)
endif()

find_package(libpsml)
if (NOT libpsml_FOUND)
  find_package(PkgConfig REQUIRED QUIET)
  pkg_check_modules(libpsml IMPORTED_TARGET GLOBAL libpsml)
  if (libpsml_FOUND)
    message(STATUS "Found libpsml via pkgconfig")
    add_library(libpsml::libpsml ALIAS PkgConfig::libpsml)
  else()
    message(FATAL_ERROR "Cannot find libpsml")
  endif()
endif()

# Check for features in (always pre-compiled, and thus available) library

include(CheckFortranSourceCompiles)

set(CMAKE_REQUIRED_LIBRARIES libpsml::libpsml)
check_fortran_source_compiles("use m_psml, only: ps_set_error_handler; end"
  LIBPSML_HAS_ERROR_PROCEDURE_POINTER SRC_EXT F90)
#
# Could check independently for the availability of the 'stat' optional
# argument to psml_read. Now it is assumed that proc pointers and 'stat'
# are implemented together in modern versions. (This is true for official releases)
#
unset(CMAKE_REQUIRED_LIBRARIES)

if( LIBPSML_HAS_ERROR_PROCEDURE_POINTER )
  set(LIBPSML_USES_PROCEDURE_POINTER TRUE)
  set(LIBPSML_READER_HAS_STAT TRUE)
else()
  set(LIBPSML_USES_PROCEDURE_POINTER FALSE)
  set(LIBPSML_READER_HAS_STAT FALSE)
endif()


set(exec_sources getz.F90 m_getopts.f90)

if(NOT LIBPSML_USES_PROCEDURE_POINTER)

 if(PSML_FIX_DIE_ISSUE)
  # Work around bug in shared library linking
  # This should only temporarily be a hack since future
  # psml versions will always rely on procedure pointers
  add_library(psml_wrappers
    STATIC
    psml_wrappers.F90
  )

  # One cannot use OBJECT libraries as their objects are not
  # passed down to subsequent dependent usages. I.e. that would cause
  # name-collisions for static libraries.
  target_link_libraries(libpsml::libpsml
    INTERFACE
    psml_wrappers
  )
 else(PSML_FIX_DIE_ISSUE)

   # Use psml_die() as another file in the executable
   
   list(APPEND exec_sources psml_wrappers.F90)

 endif(PSML_FIX_DIE_ISSUE)

else()
  list(APPEND exec_sources custom_psml_die.F90)
endif()

if( LIBPSML_USES_PROCEDURE_POINTER )
  # Deal correctly with libpsml support
  set_property(SOURCE
      getz.F90
    APPEND PROPERTY COMPILE_DEFINITIONS
    PSML_HAS_PP
  )
endif()

if( LIBPSML_READER_HAS_STAT )
  # Deal correctly with libpsml support
  set_property(SOURCE
      getz.F90
    APPEND PROPERTY COMPILE_DEFINITIONS
    PSML_READER_HAS_STAT
  )
endif()

#
# Add a copy of "psml_die" (as in former times) unconditionally
#
add_executable(test_psml ${exec_sources})

target_link_libraries(test_psml PRIVATE libpsml::libpsml)

include(CTest)

file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/install_tests")
file(COPY ../80_Hg.psml DESTINATION "${PROJECT_BINARY_DIR}/install_tests")
file(COPY ../bad.psml DESTINATION "${PROJECT_BINARY_DIR}/install_tests")

add_test(  NAME    psml_sample_getz
           COMMAND test_psml 80_Hg.psml
	   WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/install_tests"
	)
set_property (TEST psml_sample_getz
              PROPERTY PASS_REGULAR_EXPRESSION "80")

# Non-existent file
add_test(  NAME    psml_sample_getz_die
           COMMAND test_psml NonExistentFile
	   WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/install_tests"
	)


if(LIBPSML_USES_PROCEDURE_POINTER)

  set_property (TEST psml_sample_getz_die
              PROPERTY PASS_REGULAR_EXPRESSION "PSML reader error")

else()

  set_property (TEST psml_sample_getz_die
              PROPERTY PASS_REGULAR_EXPRESSION "NonExistentFile")

endif()

#-- Test of a malformed .psml file. The error might be caught by xmlf90,
#   which would either set a 'stat' return variable or stop the program.

add_test(  NAME    psml_sample_getz_parsing
           COMMAND test_psml bad.psml
	   WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/install_tests"
	)

set_property (TEST psml_sample_getz_parsing
              PROPERTY PASS_REGULAR_EXPRESSION "XML")






  
