cmake_minimum_required(VERSION 3.5.1)

include("${CMAKE_CURRENT_LIST_DIR}/version.cmake")
project(tcp_pubsub VERSION ${TCP_PUBSUB_VERSION_MAJOR}.${TCP_PUBSUB_VERSION_MINOR}.${TCP_PUBSUB_VERSION_PATCH})

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Disable default export of symbols
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)

find_package(Threads REQUIRED)
find_package(asio REQUIRED)
find_package(recycle REQUIRED)

# Include GenerateExportHeader that will create export macros for us
include(GenerateExportHeader)

# Public API include directory
set (includes
    include/tcp_pubsub/callback_data.h
    include/tcp_pubsub/executor.h
    include/tcp_pubsub/publisher.h
    include/tcp_pubsub/subscriber.h
    include/tcp_pubsub/subscriber_session.h
    include/tcp_pubsub/tcp_pubsub_logger.h
)

# Private source files
set(sources
    src/executor.cpp
    src/executor_impl.cpp
    src/executor_impl.h
    src/portable_endian.h
    src/protocol_handshake_message.h
    src/publisher.cpp
    src/publisher_impl.cpp
    src/publisher_impl.h
    src/publisher_session.cpp
    src/publisher_session.h
    src/subscriber.cpp
    src/subscriber_impl.cpp
    src/subscriber_impl.h
    src/subscriber_session.cpp
    src/subscriber_session_impl.cpp
    src/subscriber_session_impl.h
    src/tcp_header.h
    src/tcp_pubsub_logger_abstraction.h
)

add_library (${PROJECT_NAME}
    ${includes}
    ${sources}
)

# Generate version defines
configure_file("tcp_pubsub_version.h.in" "${PROJECT_BINARY_DIR}/include/tcp_pubsub/tcp_pubsub_version.h" @ONLY)

# Generate header with export macros
generate_export_header(${PROJECT_NAME}
  EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/include/tcp_pubsub/tcp_pubsub_export.h
  BASE_NAME TCP_PUBSUB
)

add_library (tcp_pubsub::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

target_link_libraries(${PROJECT_NAME}
    PRIVATE
        Threads::Threads
        $<$<BOOL:${WIN32}>:ws2_32>
        $<$<BOOL:${WIN32}>:wsock32>

        # Link header-only libs (asio & recycle) as described in this workaround:
        # https://gitlab.kitware.com/cmake/cmake/-/issues/15415#note_633938
        $<BUILD_INTERFACE:asio::asio>
        $<BUILD_INTERFACE:steinwurf::recycle>
)

target_compile_definitions(${PROJECT_NAME}
    PRIVATE
        ASIO_STANDALONE
        ASIO_DISABLE_VISIBILITY
        _WIN32_WINNT=0x0601
)

target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_14)

target_compile_options(${PROJECT_NAME} PRIVATE
                           $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
                                -Wall -Wextra>
                           $<$<CXX_COMPILER_ID:MSVC>:
                                /W4>)


# Add own public include directory
target_include_directories(${PROJECT_NAME}
  PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>   # To find the export file generated by generate_export_header
    $<INSTALL_INTERFACE:include>
  PRIVATE
    src/
)

set_target_properties(${PROJECT_NAME} PROPERTIES
    VERSION ${PROJECT_VERSION}
    SOVERSION ${PROJECT_VERSION_MAJOR}
    OUTPUT_NAME ${PROJECT_NAME}
)

##################################

include(sourcetree.cmake)
create_source_tree(${includes} ${sources})

################################################################################
### Installation rules
################################################################################

set(TCP_PUBSUB_INSTALL_CMAKE_DIR "lib/cmake/tcp_pubsub")

# Install Runtime & Libs
install(
  TARGETS ${PROJECT_NAME}
  EXPORT tcp_pubsubTargets
  
  RUNTIME
    DESTINATION "bin"
    COMPONENT tcp_pubsub_runtime

  LIBRARY
    DESTINATION "lib"
    COMPONENT tcp_pubsub_runtime

  ARCHIVE
    DESTINATION "lib"
    COMPONENT tcp_pubsub_dev
)

# Install public header files (-> dev package)
install(
  DIRECTORY "include/tcp_pubsub"
  DESTINATION "include"
  COMPONENT tcp_pubsub_dev
  FILES_MATCHING PATTERN "*.h"
)

# Install the auto-generated header with the export macros (-> dev package)
install(
  DIRECTORY "${PROJECT_BINARY_DIR}/include/tcp_pubsub"
  DESTINATION "include"
  COMPONENT tcp_pubsub_dev
  FILES_MATCHING PATTERN "*.h"
)

# Install Target.cmake file (-> dev packag)
install(
  EXPORT tcp_pubsubTargets 
  FILE tcp_pubsubTargets.cmake 
  DESTINATION ${TCP_PUBSUB_INSTALL_CMAKE_DIR}
  NAMESPACE tcp_pubsub::
  COMPONENT tcp_pubsub_dev
)

# Create and install Config.cmake file (-> dev package)

include(CMakePackageConfigHelpers)

configure_package_config_file(
  "cmake/tcp_pubsubConfig.cmake.in"
  "${CMAKE_CURRENT_BINARY_DIR}/cmake/tcp_pubsubConfig.cmake"
  INSTALL_DESTINATION ${TCP_PUBSUB_INSTALL_CMAKE_DIR}
  PATH_VARS TCP_PUBSUB_INSTALL_CMAKE_DIR
)
install(
  FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/tcp_pubsubConfig.cmake"
  DESTINATION ${TCP_PUBSUB_INSTALL_CMAKE_DIR}
  COMPONENT tcp_pubsub_dev
)

