#------------------------------------------------------------------------
# -*- mode: cmake -*-
#------------------------------------------------------------------------

cmake_minimum_required(VERSION 3.12...4.0)

set( DISABLE_INSTALLATION_OF_SWIG_HEADERS OFF CACHE BOOL "Control if SWIG headers are to be installed" )

#------------------------------------------------------------------------
# Configuration variables
#------------------------------------------------------------------------

set(LDAS_TOOLS_FRAMECPP_SWIG_PACKAGE_NAME ldas-tools-framecpp-swig)
set(LDAS_TOOLS_FRAMECPP_SWIG_VERSION      3.1.1)

set(
  PROJECT_DESCRIPTION
  "SWIG bindings for LDAS Tools frameCPP library"
  )
set(
  PROJECT_DESCRIPTION_LONG
  "This provides the swig files for the LDAS frameCPP interface"
  )

set( LDAS_TOOLS_SWIG_VERSION     4.0.0 )
set( LDAS_TOOLS_CMAKE_VERSION    1.4.0 )
set( LDAS_TOOLS_AL_VERSION       2.8.0 )
set( LDAS_TOOLS_AL_SWIG_VERSION  2.6.11 )
set( LDAS_TOOLS_FRAMECPP_VERSION 4.0.0 )
set( BOOST_MINIMUM_VERSION       1.67 )

set( FRAME_SPEC_LATEST 9 )
set( FRAME_SPEC_SET 9 8 7 6 )
set( FRAME_OUTPUT_DIR "${CMAKE_BINARY_DIR}/frames" )

string(REPLACE "-swig" "" PROJECT_BASENAME ${LDAS_TOOLS_FRAMECPP_SWIG_PACKAGE_NAME})
#------------------------------------------------------------------------

if (NOT "${CMAKE_CXX_STANDARD}")
  set(CMAKE_CXX_STANDARD 17)
endif( )
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

#------------------------------------------------------------------------
#
#------------------------------------------------------------------------

project( ${LDAS_TOOLS_FRAMECPP_SWIG_PACKAGE_NAME}
  VERSION ${LDAS_TOOLS_FRAMECPP_SWIG_VERSION}
  DESCRIPTION "${PROJECT_DESCRIPTION}"
)

#------------------------------------------------------------------------
# Locate the standard LDAS Tools cmake macro directory
#------------------------------------------------------------------------

find_package(
  LDASToolsCMake
  CONFIG
  REQUIRED
  HINTS ${CMAKE_INSTALL_PREFIX}/share/ldas-tools/cmake/Modules
  )

#========================================================================
# Start pulling in the LDAS Tools macros for easy setup
#========================================================================

find_package(AxLDASTools)
cond_set_policy(CMP0078 OLD)

#========================================================================
# Local functions
#========================================================================

include( CMakeParseArguments )

#------------------------------------------------------------------------
# Parameters:
#
# Environment:
#   FRAME_OUTPUT_DIR - Directory where the temporary frames are to be
#     stored.
#------------------------------------------------------------------------
function( cl_info_framename var version )
  #----------------------------------------------------------------------
  # Parse arguments
  #----------------------------------------------------------------------
  set(options
    FULLPATH
    )
  set(oneValueArgs
    DESC
    )
  set(multiValueArgs
    )

  cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )

  if ( NOT ARG_DESC )
    set( ARG_DESC test_frame )
  endif( )
  #----------------------------------------------------------------------
  # Generate the base filename
  #----------------------------------------------------------------------
  if ( "${ARG_DESC}" STREQUAL "fr_vect_types" )
    set( ${var} "Z-std_fr_vect_types_ver${version}-700000000-1.gwf" )
  else( )
    set( ${var} "Z-R_std_test_frame_ver${version}-600000000-1.gwf" )
  endif( )
  if ( ARG_FULLPATH )
    #--------------------------------------------------------------------
    # Prepend the output directory
    #--------------------------------------------------------------------
    set( ${var} "${FRAME_OUTPUT_DIR}/${${var}}" )
  endif( )
  #----------------------------------------------------------------------
  # Export the results
  #----------------------------------------------------------------------
  set( ${var} ${${var}} PARENT_SCOPE )
endfunction( )

function( cl_create_framefiles )
  add_custom_target( test_frames ALL )

  cx_scheme_sanitizer_set_environment(
    OUTPUT sanitizer_environment_variables_
  )

  foreach( v ${ARGN} )
    add_custom_command(
      TARGET test_frames
      POST_BUILD
      COMMAND ${sanitizer_environment_variables_}
        ${FRAMECPP_SAMPLE} --test-frame-mode --version ${v}
      COMMAND ${sanitizer_environment_variables_}
        ${FRAMECPP_SAMPLE} --version ${v}
	      --description std_fr_vect_types_ver${v}
	      --start-time 700000000
	      --duration 1
      #COMMAND
      #  ${FRAMECPP_DUMP_OBJECTS}
      #  --silent-data
      #  Z-std_fr_vect_types_ver${v}-700000000-1.gwf
      #COMMAND
      #  ${FRAMECPP_DUMP_TOC}
      #  Z-std_fr_vect_types_ver${v}-700000000-1.gwf
      WORKING_DIRECTORY ${FRAME_OUTPUT_DIR}
    )
    cl_info_framename( FULLNAME ${v} FULLPATH )
    cl_info_framename( FR_VECT_FULLNAME ${v} FULLPATH DESC fr_vect )
    set_source_files_properties(
      ${FULLNAME} ${FR_VECT_FULLNAME}
      PROPERTIES
        GENERATED TRUE
    )
  endforeach( )
endfunction( )

#========================================================================
# Start pulling in the LDAS Tools macros for easy setup
#========================================================================

cm_init(
  ${LDAS_TOOLS_FRAMECPP_SWIG_PACKAGE_NAME}
  "${LDAS_TOOLS_FRAMECPP_SWIG_VERSION}"
  ${LDAS_TOOLS_BUG_REPORT_URL}
  ${LDAS_TOOLS_FRAMECPP_SWIG_PACKAGE_NAME}
  ${LDAS_TOOLS_HOMEPAGE_URL}
  DESCRIPTION "${PROJECT_DESCRIPTION}"
  )

set( PROJECT_CONFIG_PATH "${PROJECT_SOURCE_DIR}/config" )

set( PROJECT_CONFIG_FILENAME
  "${CMAKE_CURRENT_BINARY_DIR}/common/framecpp_swig_config.h" )

ch_top(
    "#ifndef FRAMECPP_SWIG_CONFIG_H"
    "#define FRAMECPP_SWIG_CONFIG_H"
    " "
)
ch_bottom(
    " "
    "#endif /* FRAMECPP_SWIG_CONFIG_H */"
)

cx_scheme_sanitizer(
  ALLOW_WARNINGS
  ENABLE_ASAN
  ENABLE_USE_AFTER_SCOPE
  DISABLE_DETECT_ODR_VIOLATION
  DISABLE_RECOVERY_ASAN
  SUPPRESSION_FILE_ASAN ${CMAKE_SOURCE_DIR}/asan_suppressions.txt
  ENABLE_LSAN
  DISABLE_RECOVERY_LSAN
  SUPPRESSION_FILE_LSAN ${CMAKE_SOURCE_DIR}/lsan_suppressions.txt
  ENABLE_MSAN
  DISABLE_RECOVERY_MSAN
  SUPPRESSION_FILE_MSAN ${CMAKE_SOURCE_DIR}/msan_suppressions.txt
  ENABLE_TSAN
  DISABLE_RECOVERY_TSAN
  SUPPRESSION_FILE_TSAN ${CMAKE_SOURCE_DIR}/tsan_suppressions.txt
  ENABLE_UBSAN
  DISABLE_RECOVERY_UBSAN
  SUPPRESSION_FILE_UBSAN ${CMAKE_SOURCE_DIR}/ubsan_suppressions.txt
)

cx_check_compile_hardening( )
# cx_cxx_warnings_as_errors( Debug )

#=======================================================================
# Check for key programs
#=======================================================================

find_package(SWIG 2.0.4 REQUIRED)
include(${SWIG_USE_FILE})

if( NOT ENABLE_DOCUMENTATION_ONLY )
  cm_pkg_check_modules(
    PREFIX LDASTOOLS
    REQUIRED
    MODULES
      framecpp>=${LDAS_TOOLS_FRAMECPP_VERSION}
      ldastoolsal>=${LDAS_TOOLS_AL_VERSION}
      )
endif( )
unset(LDASTOOLS_CFLAGS_ONLY_I)
if ( LDASTOOLS_INCLUDE_DIRS )
  foreach(dir ${LDASTOOLS_INCLUDE_DIRS})
    list(APPEND LDASTOOLS_CFLAGS_ONLY_I "-I${dir}")
  endforeach( )
endif( )

cx_msg_debug_variable( LDASTOOLS_FOUND )
cx_msg_debug_variable( LDASTOOLS_INCLUDE_DIRS )
cx_msg_debug_variable( LDASTOOLS_LIBRARIES )

#========================================================================
# Generate a set of test frames
#========================================================================

cm_check_progs( FRAMECPP_SAMPLE framecpp_sample )
cm_check_progs( FRAMECPP_DUMP_OBJECTS framecpp_dump_objects )
cm_check_progs( FRAMECPP_DUMP_TOC framecpp_dump_toc )

if ( NOT EXISTS ${FRAME_OUTPUT_DIR} )
  file( MAKE_DIRECTORY "${FRAME_OUTPUT_DIR}" )
endif( )

cl_create_framefiles( ${FRAME_SPEC_SET} )

add_custom_target( doc )

#========================================================================
# Traverse the tree
#========================================================================

add_subdirectory(common)
add_subdirectory(python)

# Add test subdirectory if testing is enabled
if(BUILD_TESTING)
  add_subdirectory(test)
endif()

#========================================================================
# Commit configuration information to the file
#========================================================================

cm_config_headers( ${PROJECT_CONFIG_FILENAME} )

#========================================================================
# Installation of key files
#========================================================================

#========================================================================
# Prepare the distribution
#========================================================================

cx_cpack(
  MACPORTS_CATEGORY devel
  SUBPORTS
    py27-${PROJECT_BASENAME}
    py35-${PROJECT_BASENAME}
    py36-${PROJECT_BASENAME}
    py37-${PROJECT_BASENAME}
    py38-${PROJECT_BASENAME}
  )

#========================================================================
# Report configuration information
#  CMAKE_MAKE_PROGRAM:FILEPATH
#========================================================================
cm_msg_notice( "=========================================================" )
cm_msg_notice( " Project ${PROJECT_NAME} has now ben successfully configured:" )
cm_msg_notice( " " )
cm_msg_notice( " Python settings:" )
cm_msg_notice( "      PYTHON3                        ${PYTHON3_EXECUTABLE}" )
cm_msg_notice( "      PYTHON3_VERSION                ${PYTHON3_VERSION}" )
cm_msg_notice( "      PYTHON3_VERSION_NODOTS         ${PYTHON3_VERSION_NODOTS}" )
cm_msg_notice( "      PYTHON3_VERSION_STRING         ${PYTHON3_VERSION_STRING}" )
cm_msg_notice( "      PYTHON3_LIBRARIES              ${PYTHON3_LIBRARIES}" )
cm_msg_notice( "      PYTHON3LIBS_VERSION_STRING     ${PYTHON3LIBS_VERSION_STRING}" )
cm_msg_notice( " " )
cm_msg_notice( " Additional configuration information:" )
cm_msg_notice( "      CMAKE_INSTALL_PREFIX           ${CMAKE_INSTALL_PREFIX}" )
cm_msg_notice( "      CMAKE_PREFIX_PATH              ${CMAKE_PREFIX_PATH}" )
cm_msg_notice( "      LDASTOOLS_FOUND                ${LDASTOOLS_FOUND}" )
cm_msg_notice( "      LDASTOOLS_INCLUDE_DIRS         ${LDASTOOLS_INCLUDE_DIRS}" )
cm_msg_notice( "      LDASTOOLS_LIBRARIES            ${LDASTOOLS_LIBRARIES}" )
cm_msg_notice( "      LDASTOOLS_LIBRARIES_FULL_PATH  ${LDASTOOLS_LIBRARIES_FULL_PATH}" )
cm_msg_notice( "      LDASTOOLS_LINK_LIBRARIES       ${LDASTOOLS_LINK_LIBRARIES}" )
cm_msg_notice( " " )
cm_msg_notice( " installation directories:" )
cm_msg_notice( "      CMAKE_INSTALL_BINDIR           ${CMAKE_INSTALL_BINDIR}" )
cm_msg_notice( "      CMAKE_INSTALL_DATADIR          ${CMAKE_INSTALL_DATADIR}" )
cm_msg_notice( " " )
cm_msg_notice( "  Sanitizers:" )
cm_msg_notice( "      Active:                         ${CX_SCHEME_SANITIZERS_ACTIVE}" )
cm_msg_notice( " " )
cm_msg_notice( "  Now run 'cmake --build .' to build ${PROJECT_NAME}" )
cm_msg_notice( "  and run 'cpack' to package ${PROJECT_NAME}" )
cm_msg_notice( "=========================================================" )
