#set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES /usr/include)
#set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES /usr/include)

# Not sure we actually need this for the analyzer?
if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json")
    execute_process(
        COMMAND cmake -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json
                ${CMAKE_CURRENT_SOURCE_DIR}/compile_commands.json
    )
endif()

message("\n${BoldGreen}Now configuring library libXpertMassCore${ColourReset}\n")

# ##############################################################################
# Files
set(XpertMassCore_SRCS
    #
    # Most general features
    src/globals.cpp
    src/Utils.cpp
    src/Prop.cpp
    src/PropListHolder.cpp
    #
    # The basic chemical features
    src/Isotope.cpp
    src/IsotopicData.cpp
    src/IsotopicDataBaseHandler.cpp
    src/IsotopicDataLibraryHandler.cpp
    src/IsotopicDataUserConfigHandler.cpp
    src/IsotopicDataManualConfigHandler.cpp
    #
    src/ChemicalGroupRule.cpp
    src/ChemicalGroup.cpp
    src/PkaPhPi.cpp
    src/PkaPhPiDataParser.cpp
    #
    src/Formula.cpp
    src/Ionizer.cpp
    src/Modif.cpp
    src/Monomer.cpp
    src/MonomerDictionary.cpp
    #
    src/CrossLinker.cpp
    src/CrossLink.cpp
    src/CrossLinkedRegion.cpp
    #
    src/Averagine.cpp
    #
    src/MassCollection.cpp
    #
    # Calculation engine configuration
    src/CalcOptions.cpp
    #
    # The mass peak shaping feature
    src/MassPeakShaper.cpp
    src/MassPeakShaperConfig.cpp
    src/IsotopicClusterShaper.cpp
    src/IsotopicClusterGenerator.cpp
    #
    # The chemical reactions
    src/CleavageMotif.cpp
    src/CleavageRule.cpp
    src/CleavageAgent.cpp
    src/CleavageConfig.cpp
    src/Cleaver.cpp
    src/FragmentationRule.cpp
    src/FragmentationConfig.cpp
    src/FragmentationPathway.cpp
    src/Fragmenter.cpp
    #
    # Polymer chemistry definition
    src/PolChemDefSpec.cpp
    src/PolChemDef.cpp
    #
    # Sequence entities
    src/IndexRange.cpp
    src/IndexRangeCollection.cpp
    src/Sequence.cpp
    src/Polymer.cpp
    src/Oligomer.cpp
    src/OligomerPair.cpp
    src/OligomerCollection.cpp
    #
    # The network functionality
    src/MassDataCborBaseHandler.cpp
    src/MassDataCborMassSpectrumHandler.cpp
    src/MassDataServer.cpp
    src/MassDataClient.cpp
    #
    # Recent files handler
    src/RecentFilesHandler.cpp
    #
    # Tolerance
    src/Tolerance.cpp
    #
    # Scripting-related
    src/XpertMassCoreJavaScript.cpp
    src/jsclassregistrar.cpp
    #
    # Deconvolution of mass spectra
    src/AbstractLowMassDeconvolver.cpp
    src/LowMassDeconvolverNoLabelling.cpp
    src/LowMassDeconvolverFullLabelling.cpp
)

qt6_add_resources(XpertMassCore_QRC_CPP xpertmasscore_resources.qrc)

# This is only a workaround to the fact that although we list *.hpp and *.cpp
# files as source files for the add_target() command, and although we
# have the Q_NAMESPACE in the Enums namespace, the moc_globals.cpp file is
# not added to the image files linked into the library).
# This has as a bad effect of having not the Enums staticMetaObject in the
# library, which then translates into an undefined symbol linker error.
qt6_wrap_cpp(Core_MOC_SOURCES includes/MsXpS/libXpertMassCore/globals.hpp)

# Force the qFatal() message to output all we need (filename, function)...
add_definitions(-DQT_MESSAGELOGCONTEXT)

# Because the header files are in their own directory and not along the source
# files, we need to have them listed explicitely for automoc to work properly
# below.

# Create a variable to hold the 'includes' directory *relative* to the current
# CMakeLists.txt file.

set(INCLUDES_DIR "${CMAKE_CURRENT_LIST_DIR}/includes")
file(GLOB_RECURSE XpertMassCore_HEADERS ${INCLUDES_DIR}/*.h ${INCLUDES_DIR}/*.hpp)
message(STATUS "Included the header files from ${INCLUDES_DIR}: \n\
  ${XpertMassCore_HEADERS}"
)

# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)

# Sure we need this ? add_library(compiler_flags INTERFACE)
# target_compile_features(compiler_flags INTERFACE cxx_std_11)

if(CMAKE_COMPILER_IS_GNUCXX AND CODE_COVERAGE)
    include(CodeCoverage)
    append_coverage_compiler_flags()
endif()

# ##############################################################################
# Configuration of the binary to be built
# ##############################################################################

# Only now can we add the library, because we have defined the sources.

# ##############################################################################
# Build the static lib
add_library(
    Core_static STATIC
    ${XpertMassCore_HEADERS}
    ${XpertMassCore_SRCS}
    ${Core_MOC_SOURCES} # See explanation above about globals.cpp Enums
    ${XpertMassCore_QRC_CPP}
    ${PLATFORM_SPECIFIC_SOURCES}
)

# So that the JavaScript reference text is extracted before using
# xpertmasscore_resources.qrc that reference it.
add_dependencies(Core_static extract_class_js_ref_text)

set_target_properties(
    Core_static
    PROPERTIES # Set target properties for namespace
               EXPORT_NAME "Core_static"
               OUTPUT_NAME XpertMassCore
               LINK_FLAGS "-Wl,--whole-archive"
)

target_link_libraries(
    Core_static
    PUBLIC PappsoMSpp::Core
           IsoSpec++::IsoSpec++
           Qt6::Core
           Qt6::Svg
           Qt6::Xml
           Qt6::Network
           Qt6::Qml
)

if(PROFILING)
    target_link_options(Core_static PRIVATE -pg)
endif()

# The install interface that is ${prefix}/include.

target_include_directories(
    Core_static
    PUBLIC # These include directories are for building of this lib.
           $<BUILD_INTERFACE:${INCLUDES_DIR}>
           # These include directories are for users of this lib.
           $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

get_target_property(Core_static_INCLUDES Core_static INCLUDE_DIRECTORIES)
message(STATUS "Core_static_INCLUDES: ${Core_static_INCLUDES}")

install(
    TARGETS Core_static
    EXPORT XpertMassCoreStaticTargets.cmake
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    INCLUDES
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

# Export static targets
install(
    EXPORT XpertMassCoreStaticTargets.cmake
    FILE XpertMassCoreStaticTargets.cmake
    NAMESPACE XpertMass::
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/XpertMass
)

export(
    EXPORT XpertMassCoreStaticTargets.cmake
    FILE "${CMAKE_CURRENT_BINARY_DIR}/XpertMassCoreStaticTargets.cmake"
    NAMESPACE XpertMass::
)

# ##############################################################################
# Build the shared lib
add_library(
    Core SHARED
    ${XpertMassCore_HEADERS}
    ${XpertMassCore_SRCS}
    ${Core_MOC_SOURCES} # See explanation above about globals.cpp Enums
    ${XpertMassCore_QRC_CPP}
    ${PLATFORM_SPECIFIC_SOURCES}
)

set_target_properties(
    Core
    PROPERTIES # Set target properties for namespace
               EXPORT_NAME "Core"
               # The actual shared library name: libXpertMass
               OUTPUT_NAME XpertMassCore
               VERSION ${PROJECT_VERSION}
               SOVERSION ${PROJECT_VERSION_MAJOR}
               LINK_FLAGS "-Wl,--no-as-needed"
               POSITION_INDEPENDENT_CODE ON
)

# So that the JavaScript reference text is extracted before using
# xpertmasscore_resources.qrc that reference it.
add_dependencies(Core extract_class_js_ref_text)

target_link_libraries(
    Core
    PUBLIC PappsoMSpp::Core
           IsoSpec++::IsoSpec++
           Qt6::Core
           Qt6::Xml
           Qt6::Network
           Qt6::Qml
)

if(PROFILING)
    target_link_options(Core PRIVATE -pg)
endif()

# The INSTALL_INTERFACE that is ${prefix}/include

target_include_directories(
    Core
    PUBLIC # These include directories are for building of this lib.
           $<BUILD_INTERFACE:${INCLUDES_DIR}>
           # These include directories are for users of this lib.
           $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

get_target_property(Core_INCLUDES Core INCLUDE_DIRECTORIES)
message(STATUS "Core_INCLUDES: ${Core_INCLUDES}")

target_compile_definitions(Core PRIVATE "EXPORT_LIB_SYMBOLS")

# This is to avoid the "include_next(math.h) file not found" error.
if(WIN32)
    set_target_properties(Core_static PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)
    set_target_properties(Core PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)
endif()

install(
    TARGETS Core
    EXPORT XpertMassCoreSharedTargets
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    INCLUDES
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

# Export shared targets
install(
    EXPORT XpertMassCoreSharedTargets
    FILE XpertMassCoreSharedTargets.cmake
    NAMESPACE XpertMass::
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/XpertMass
)

export(
    EXPORT XpertMassCoreSharedTargets
    FILE "${CMAKE_CURRENT_BINARY_DIR}/XpertMassCoreSharedTargets.cmake"
    NAMESPACE XpertMass::
)

# ##############################################################################
# Common installation configuration

message("The directory containing the includes: ${CMAKE_CURRENT_LIST_DIR}/includes/MsXpS/libXpertMassCore")

install(
    DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/includes/MsXpS/libXpertMassCore
    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/MsXpS"
)
install(
    FILES ${CMAKE_CURRENT_LIST_DIR}/includes/MsXpS/export-import-config.h
    DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/MsXpS"
)

message("")
message(STATUS "CMAKE_CURRENT_BINARY_DIR: ${CMAKE_CURRENT_BINARY_DIR}")
message("")
message(STATUS "${BoldGreen}Finished configuration of libXpertMass.${ColourReset}")
message("")

message("\n${BoldGreen}Done configuring library libXpertMassCore${ColourReset}\n")
