cmake_minimum_required(VERSION 3.20)
project(libparitypp VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

find_package(libnetplus REQUIRED)

# Library sources
set(PARITYPP_SOURCES
    src/galois.cpp
    src/matrix.cpp
    src/parity.cpp
    src/protocol.cpp
    src/auth.cpp
    src/server.cpp
    src/client.cpp
)

set(PARITYPP_HEADERS
    include/paritypp/galois.h
    include/paritypp/matrix.h
    include/paritypp/parity.h
    include/paritypp/protocol.h
    include/paritypp/auth.h
    include/paritypp/server.h
    include/paritypp/client.h
)

# Shared library
add_library(paritypp SHARED ${PARITYPP_SOURCES})
target_include_directories(paritypp
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/include/paritypp
)
target_link_libraries(paritypp PUBLIC netplus::netplus)
set_target_properties(paritypp PROPERTIES
    VERSION ${PROJECT_VERSION}
    SOVERSION 1
)

# Static library
add_library(paritypp-static STATIC ${PARITYPP_SOURCES})
target_include_directories(paritypp-static
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/include/paritypp
)
if(TARGET netplus::netplus-static)
    target_link_libraries(paritypp-static PUBLIC netplus::netplus-static)
else()
    target_link_libraries(paritypp-static PUBLIC netplus::netplus)
endif()

set_target_properties(paritypp-static PROPERTIES
    OUTPUT_NAME paritypp-static
)

# Test executables
add_executable(paritypp_test test/parity_test.cpp)
target_link_libraries(paritypp_test PRIVATE paritypp-static)

add_executable(paritypp_consistency_test test/consistency_test.cpp)
target_link_libraries(paritypp_consistency_test PRIVATE paritypp-static)
target_link_libraries(paritypp_consistency_test PRIVATE pthread)

# Install
include(GNUInstallDirs)

install(TARGETS paritypp paritypp-static
    EXPORT parityppTargets
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install(DIRECTORY include/paritypp/
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/paritypp
    FILES_MATCHING PATTERN "*.h"
)

install(EXPORT parityppTargets
    FILE parityppTargets.cmake
    NAMESPACE paritypp::
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/paritypp
)

# Config file
include(CMakePackageConfigHelpers)

configure_package_config_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/parityppConfig.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/parityppConfig.cmake
    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/paritypp
)

write_basic_package_version_file(
    ${CMAKE_CURRENT_BINARY_DIR}/parityppConfigVersion.cmake
    VERSION ${PROJECT_VERSION}
    COMPATIBILITY SameMajorVersion
)

install(FILES
    ${CMAKE_CURRENT_BINARY_DIR}/parityppConfig.cmake
    ${CMAKE_CURRENT_BINARY_DIR}/parityppConfigVersion.cmake
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/paritypp
)
