#------------------------------------------------------------------------
# -*- mode: cmake -*-
#------------------------------------------------------------------------
#
# LDASTools Frame Utility Library  - Frame Utility library
#
# Copyright (C) 2018 California Institute of Technology
#
# LDASTools Frame Utility Library  is free software; you may redistribute
# it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2 (GPLv2)
#  of the License or at your discretion, any later version.
#
# LDASTools Frame Utility Library is distributed in the hope that it will
# be useful, but without any warranty or even the implied warranty of
# merchantability or fitness for a particular purpose. See the GNU
# General Public License (GPLv2) for more details.
#
# Neither the names of the California Institute of Technology (Caltech),
# The Massachusetts Institute of Technology (M.I.T), The Laser
# Interferometer Gravitational-Wave Observatory (LIGO), nor the names
# of its contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# You should have received a copy of the licensing terms for this
# software included in the file LICENSE located in the top-level
# directory of this package. If you did not, you can view a copy at
# http://dcc.ligo.org/M1500244/LICENSE
#
#------------------------------------------------------------------------

set( LDAS_TOOLS_AL_PACKAGE_NAME ldas-tools-al )
set( LDAS_TOOLS_AL_VERSION      2.7.0 )

set(
  PROJECT_DESCRIPTION
  "Abstraction library used by LDAS Tools"
  )
set(
  PROJECT_DESCRIPTION_LONG
  "This provides a collection of classes and fuctions"
  "allowing for system level abstraction"
  "as used by the LDAS Tools Suite."
  )

set( LDAS_TOOLS_CMAKE_VERSION   1.3.1 )

set( BOOST_MINIMUM_VERSION 1.67 )

cmake_minimum_required(VERSION 3.12)
#------------------------------------------------------------------------
#------------------------------------------------------------------------

if (NOT "${CMAKE_CXX_STANDARD}")
  set(CMAKE_CXX_STANDARD 17)
endif( )
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)
if ( NOT CMAKE_OSX_ARCHITECTURES )
  set( CMAKE_OSX_ARCHITECTURES x86_64 )
endif( )

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

project( ${LDAS_TOOLS_AL_PACKAGE_NAME} )

#------------------------------------------------------------------------
# Configuration options
#------------------------------------------------------------------------

set( ENABLE_DOCUMENTATION_ONLY FALSE CACHE BOOL "Enable only building of documentation" )

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

include( GNUInstallDirs )

set(LDAS_TOOLS_CMAKE_MODULES_DIRS
  ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/ldas-tools/cmake/Modules
  ${CMAKE_INSTALL_FULL_DATADIR}/ldas-tools/cmake/Modules
  )

find_package(
  LDASToolsCMake
  CONFIG
  REQUIRED
  HINTS ${LDAS_TOOLS_CMAKE_MODULES_DIRS}
  PATHS ${LDAS_TOOLS_CMAKE_MODULES_DIRS}
  )

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

find_package(AxLDASTools REQUIRED)

cx_msg_debug_variable( CMAKE_INSTALL_DOCDIR )
cx_msg_debug_variable( CMAKE_INSTALL_FULL_DOCDIR )

cx_msg_debug_variable( BOOST_INCLUDEDIR )
cx_msg_debug_variable( BOOST_LIBRARYDIR )

cm_init(
  ${LDAS_TOOLS_AL_PACKAGE_NAME}
  "${LDAS_TOOLS_AL_VERSION}"
  ${LDAS_TOOLS_BUG_REPORT_URL}
  ${LDAS_TOOLS_AL_PACKAGE_NAME}
  ${LDAS_TOOLS_HOMEPAGE_URL}
  DESCRIPTION "${PROJECT_DESCRIPTION}"
  )

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

#dnl =====================================================================
#dnl  Prepare a header file to store the glorious configuration info
#dnl =====================================================================

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

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

#dnl =====================================================================
#dnl  Check for the operating system
#dnl =====================================================================
#
#AX_LDAS_OS
#AX_LDAS_CHECK_OS_VARIABLE_LIBRARY_LOAD_PATH
#
#dnl =====================================================================
#dnl  Check for compilers and language features
#dnl =====================================================================
#
#AX_LDAS_PROG_CC
#
cx_ldas_prog_cxx( )
#AX_CXX_COMPILE_STDCXX([11],[noext],[mandatory])
#AX_LDAS_CXX_CONSTEXPR
#AX_LDAS_CXX_EXCEPTIONS_RETHROW
#AX_LDAS_CXX_TEMPLATE_ALIASES
#AX_LDAS_CXX_TEMPLATE_ALIASES_VIA_USING
#AX_LDAS_CXX_TEMPLATE_AS_TEMPLATE_PARAMETER
#
#AX_LDAS_ARG_WITH_OPTIMIZATION
#
#dnl =====================================================================
#dnl  Checking if the OS is 64 bit
#dnl =====================================================================
#
#AX_LDAS_SYS_64BIT_OS
#

cx_scheme_sanitizer(
  ALLOW_WARNINGS
  ENABLE_ASAN
  ENABLE_USE_AFTER_SCOPE
  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 )

#dnl =====================================================================
#dnl  Check for key programs
#dnl =====================================================================
#
#AX_LDAS_PROG_LIBTOOL
#AX_LDAS_PROG_PKGBUILDER
#AX_LDAS_PROG_DOXYGEN
#AX_LDAS_PROG_VALGRIND
#AX_LDAS_PROG_ABI_COMPLIANCE_CHECKER
#AX_LDAS_PROG_ABI_DUMPER
#
#AC_CHECK_PROGS([EXPR],[expr])
#
#dnl =====================================================================
#dnl  Check for header files
#dnl =====================================================================

cm_header_stdc( )
cm_check_headers(mntent.h)
cm_check_headers(sys/kinfo_proc.h)
cm_check_headers(sys/mnttab.h)
cm_check_headers(sys/propppc.h)
cm_check_headers(sys/stat.h)
cm_check_headers(sys/sysctl.h)
cm_check_headers(sys/sysinfo.h)
cm_check_headers(sys/types.h)
cm_check_headers(dirent.h)
cm_check_headers(procfs.h)
cm_check_headers(stdlib.h)

# Use LDAS Tools Boost detection (handles conda header-only libraries)
cx_boost_base(${BOOST_MINIMUM_VERSION})
cx_boost_log()
cx_boost_log_setup()
cx_boost_thread()
cx_boost_system()
cx_boost_filesystem()
cx_boost_date_time()
cx_boost_program_options()

# Verify all components found
set(_required_components LOG LOG_SETUP THREAD SYSTEM FILESYSTEM DATE_TIME PROGRAM_OPTIONS)
foreach(_comp ${_required_components})
  if(NOT BOOST_${_comp}_FOUND)
    message(FATAL_ERROR "Required Boost component ${_comp} not found")
  endif()
endforeach()

# Build BOOST_CPPFLAGS for pkg-config
list(APPEND BOOST_CPPFLAGS "-I${BOOST_INCLUDE_DIR}")

# Build BOOST_LDFLAGS for pkg-config from component LDFLAGS
set(BOOST_LDFLAGS "")
foreach(_comp ${_required_components})
  if(BOOST_${_comp}_LDFLAGS)
    list(APPEND BOOST_LDFLAGS ${BOOST_${_comp}_LDFLAGS})
  endif()
endforeach()

# Convert lists to space-separated strings for pkg-config
string(REPLACE ";" " " BOOST_LDFLAGS "${BOOST_LDFLAGS}")
string(REPLACE ";" " " BOOST_CPPFLAGS "${BOOST_CPPFLAGS}")

cx_check_header_for_subst(unordered_map     HAVE_UNORDERED_MAP)
cx_check_header_for_subst(tr1/unordered_map HAVE_TR1_UNORDERED_MAP)
cx_check_header_for_subst(hash_map          HAVE_HASH_MAP)
cx_check_header_for_subst(ext/hash_map      HAVE_EXT_HASH_MAP)
cx_check_header_for_subst(map               HAVE_MAP)

# =======================================================================
#  Check for structures/sizes
# =======================================================================

cm_c_bigendian( )
if( WORDS_BIGENDIAN )
  set( LDAS_WORDS_BIGENDIAN 1)
else( )
  set( LDAS_WORDS_BIGENDIAN 0)
endif( )
cx_check_sizes( )
cm_define(
  VARIABLE LDAS_WORDS_BIGENDIAN
  VALUE ${LDAS_WORDS_BIGENDIAN}
  DESCRIPTION "Set to 1 if system is bigendian" )
cx_struct_procfs_psinfo( )
cx_struct_procfs_stat( )

#dnl =====================================================================
#dnl  Check for individual libraries
#dnl =====================================================================

set( THREADS_PREFER_PTHREAD ON )
find_package( Threads REQUIRED )

cx_thread( )
cx_lib_socket_nsl( )
cm_check_lib(rt clock_gettime)
# cm_check_lib(pthread pthread_cancel)
cx_check_lib_umem( )
cx_check_lib_z( )
#
#dnl =====================================================================
#dnl  Check for individual functions
#dnl =====================================================================
#
include(CheckSymbolExists)

cm_check_funcs(clock_gettime)
cm_func_strerror_r( )
cm_check_funcs(fpathconf)
cm_check_funcs(dirfd)
cm_check_funcs(fdopendir)
check_symbol_exists(
  dirfd
  "sys/types.h;dirent.h"
  HAVE_DIRFD_MACRO
  )
cm_define(
  VARIABLE HAVE_DIRFD_MACRO
  VALUE ${HAVE_DIRFD_MACRO}
  DESCRIPTION "Defined if dirfd() is a macro in dirent.h" )
cx_check_func_swap_all( )
cx_check_pthread_read_write_lock( )

#dnl =====================================================================
#dnl  Check for supported classes
#dnl =====================================================================
#
#AX_LDAS_CXX_TEMPLATE_MOVE
#AX_LDAS_CXX_UNIQUE_PTR
#
#dnl =====================================================================
#dnl 
#dnl =====================================================================
#
#AC_DEFINE([LIBEXECDIR],["@libexecdir@"],[Directory for installing executables that other other programs run])
#AX_LDAS_DEF_VARIABLE([PACKAGE_VERSION_NUMERIC],
#			  ["`echo ${PACKAGE_VERSION} |  ${SED} -e 's/[[~]][(]alpha|beta[)].*$//'`"])
#
#========================================================================
# Traverse the tree
#========================================================================

add_subdirectory(src)
add_subdirectory(test)
add_subdirectory(doc)

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

cm_config_headers( ${PROJECT_CONFIG_FILENAME} )

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

cx_cpack(
  MACPORTS_CATEGORY science
  MAINTAINER "Edward Maros <ed.maros@ligo.org>"
  )

#========================================================================
# Report configuration information
#  CMAKE_MAKE_PROGRAM:FILEPATH
#========================================================================
get_target_property( my_cxx_flags ldastoolsal LINK_OPTIONS )
cm_msg_notice( "=========================================================")
cm_msg_notice( "  Project ${PROJECT_NAME} has now ben successfully configured:")
cm_msg_notice( " " )
cm_msg_notice( "  configuration information:" )
cm_msg_notice( "      CMAKE_C_FLAGS                  ${CMAKE_C_FLAGS}" )
cm_msg_notice( "      CMAKE_CXX_FLAGS                ${EXTRA_PKGCONFIG_CFLAGS}")
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( "      CMAKE_INSTALL_PREFIX           ${CMAKE_INSTALL_PREFIX}" )
cm_msg_notice( "      CMAKE_INSTALL_DOCDIR           ${CMAKE_INSTALL_DOCDIR}" )
cm_msg_notice( "      CMAKE_INSTALL_FULL_DOCDIR      ${CMAKE_INSTALL_FULL_DOCDIR}" )
cm_msg_notice( " " )
cm_msg_notice( "  Boost Libraries:" )
cm_msg_notice( "      BOOST_LIBRARY_DIR              ${BOOST_LIBRARY_DIR}" )
cm_msg_notice( "      BOOST_TARGETS                  ${BOOST_TARGETS}" )
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( "=========================================================")
#dnl =====================================================================
#dnl  Generate local output
#dnl =====================================================================
#
#AC_OUTPUT(
#	ldas-tools-al.spec
#	config/Makefile
#	config/autotools/Makefile
#	config/autotools/m4/Makefile
#	config/autotools/make/Makefile
#	config/scripts/Makefile
#	config/swig/Makefile
#	config/data/Makefile
#) dnl AC_OUTPUT
#
#AC_OUTPUT(
#	Makefile
#	ldastoolsal.pc
#	ldastoolsal-uninstalled.pc
#	src/Makefile
#	src/types.hh
#	src/ldas_types.h
#	src/reverse.hh
#	src/unordered_map.hh
#	test/Makefile
#	doc/Makefile
#	debian/Makefile
#) dnl AC_OUTPUT - general
#
