# =========================== LICENSE =================================
#
# Copyright (C) 2016 - 2022 Continental Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# =========================== LICENSE =================================

cmake_minimum_required(VERSION 3.13)

include("${CMAKE_CURRENT_LIST_DIR}/version.cmake")
project(udpcap VERSION ${UDPCAP_VERSION_MAJOR}.${UDPCAP_VERSION_MINOR}.${UDPCAP_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(npcap        REQUIRED)
find_package(pcapplusplus REQUIRED)
find_package(asio         REQUIRED)

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

# Public API include directory
set (includes
    include/udpcap/host_address.h
    include/udpcap/npcap_helpers.h
    include/udpcap/udpcap_socket.h
)

# Private source files
set(sources
    src/host_address.cpp
    src/ip_reassembly.cpp
    src/ip_reassembly.h
    src/log_debug.h
    src/npcap_helpers.cpp
    src/udpcap_socket.cpp
    src/udpcap_socket_private.cpp
    src/udpcap_socket_private.h
)

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

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

# Generate header with export macros
generate_export_header(${PROJECT_NAME}
  EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/include/udpcap/udpcap_export.h
  BASE_NAME UDPCAP
)

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

target_link_libraries(${PROJECT_NAME}
    PRIVATE #TODO: This used to be private
        npcap::npcap
        pcapplusplus::pcapplusplus
        $<$<BOOL:${WIN32}>:ws2_32>
        $<$<BOOL:${WIN32}>:wsock32>

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

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}
)

get_target_property(target_type ${PROJECT_NAME} TYPE)
if (target_type STREQUAL STATIC_LIBRARY)
  set_target_properties(${PROJECT_NAME}
    PROPERTIES INTERFACE_LINK_OPTIONS
    -DELAYLOAD:wpcap.dll
  )
else()
  set_target_properties(${PROJECT_NAME}
    PROPERTIES LINK_FLAGS
    -DELAYLOAD:wpcap.dll
  )
endif()

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

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

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

set(UDPCAP_INSTALL_CMAKE_DIR "lib/cmake/udpcap")

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

  LIBRARY
    DESTINATION "lib"
    COMPONENT udpcap_runtime

  ARCHIVE
    DESTINATION "lib"
    COMPONENT udpcap_dev
)

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

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

# Install Target.cmake file (-> dev packag)
install(
  EXPORT udpcapTargets 
  FILE udpcapTargets.cmake 
  DESTINATION ${UDPCAP_INSTALL_CMAKE_DIR}
  NAMESPACE udpcap::
  COMPONENT udpcap_dev
)

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

include(CMakePackageConfigHelpers)

get_target_property(target_type ${PROJECT_NAME} TYPE)
if (target_type STREQUAL STATIC_LIBRARY)
  set(CONFIG_INPUT_FILENAME "udpcapConfig-static.cmake.in")
else()
  set(CONFIG_INPUT_FILENAME "udpcapConfig-shared.cmake.in")
endif()

configure_package_config_file(
  "cmake/${CONFIG_INPUT_FILENAME}"
  "${CMAKE_CURRENT_BINARY_DIR}/cmake_/udpcapConfig.cmake"
  INSTALL_DESTINATION ${UDPCAP_INSTALL_CMAKE_DIR}
  PATH_VARS UDPCAP_INSTALL_CMAKE_DIR
)
install(
  FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake_/udpcapConfig.cmake"
  DESTINATION ${UDPCAP_INSTALL_CMAKE_DIR}
  COMPONENT udpcap_dev
)

