cmake_minimum_required(VERSION 3.25)
project(BridgeHead VERSION 0.1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

option(BRIDGEHEAD_BUILD_TESTS        "Build test suite"                      ON)
option(BRIDGEHEAD_INTEGRATION_TESTS  "Enable live AD integration tests"      OFF)
option(BRIDGEHEAD_BUILD_TOOLS        "Build CLI tools (adws_list)"           OFF)

# BRIDGEHEAD_INTEGRATION_TESTS implies BRIDGEHEAD_BUILD_TESTS.
if(BRIDGEHEAD_INTEGRATION_TESTS AND NOT BRIDGEHEAD_BUILD_TESTS)
    message(WARNING
        "BRIDGEHEAD_INTEGRATION_TESTS=ON requires BRIDGEHEAD_BUILD_TESTS=ON -- enabling it automatically.")
    set(BRIDGEHEAD_BUILD_TESTS ON CACHE BOOL "Build test suite" FORCE)
endif()

include(cmake/Dependencies.cmake)

# ── Core library ────────────────────────────────────────────────────────────
add_library(bridgehead STATIC
    src/transport/TcpSocket.cpp
    src/framing/NmfFramer.cpp
    src/auth/NnsSession.cpp
    src/soap/NbfseDictionary.cpp
    src/soap/NbfseCodec.cpp
    src/adws/AdwsClient.cpp
    src/adws/AdwsClientAsync.cpp
    src/adws/AdwsClientPool.cpp
    src/adws/SecurityDescriptor.cpp
)

# Platform-specific auth backend
if(WIN32)
    target_sources(bridgehead PRIVATE src/auth/platform/SspiNegotiator.cpp)
    # PUBLIC: consumers linking the static lib must also resolve ws2_32/secur32.
    target_link_libraries(bridgehead PUBLIC ws2_32 secur32)
else()
    target_sources(bridgehead PRIVATE src/auth/platform/GssApiNegotiator.cpp)
    # GSSAPI — requires libgssapi_krb5 (MIT Kerberos 1.9+) or Heimdal.
    # Install libkrb5-dev (Debian/Ubuntu) or krb5-devel (Fedora/RHEL).
    find_library(GSSAPI_LIB NAMES gssapi_krb5 REQUIRED)
    target_link_libraries(bridgehead PUBLIC ${GSSAPI_LIB})
endif()

target_include_directories(bridgehead PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_compile_features(bridgehead PUBLIC cxx_std_20)
target_link_libraries(bridgehead PRIVATE pugixml::pugixml)

# Suppress MSVC warnings about std functions
if(MSVC)
    target_compile_definitions(bridgehead PRIVATE
        _CRT_SECURE_NO_WARNINGS
        _WINSOCK_DEPRECATED_NO_WARNINGS
        NOMINMAX
        WIN32_LEAN_AND_MEAN
    )
endif()

# ── Tools ───────────────────────────────────────────────────────────────────
if(BRIDGEHEAD_BUILD_TOOLS)
    add_subdirectory(tools)
endif()

# ── Tests ───────────────────────────────────────────────────────────────────
if(BRIDGEHEAD_BUILD_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()

# ── Optional Doxygen docs target ─────────────────────────────────────────────
find_package(Doxygen OPTIONAL_COMPONENTS dot)
if(DOXYGEN_FOUND)
    add_custom_target(docs
        COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        COMMENT "Generating API documentation with Doxygen"
        VERBATIM
    )
endif()

# ── Install rules ────────────────────────────────────────────────────────────
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

# Library archive + mark include dir as part of the installed interface
install(TARGETS bridgehead
    EXPORT      bridgeheadTargets
    ARCHIVE     DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

# Public headers (preserves directory structure under include/)
install(DIRECTORY include/
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

# CMake targets file (bridgehead::bridgehead imported target)
install(EXPORT bridgeheadTargets
    FILE        bridgeheadTargets.cmake
    NAMESPACE   bridgehead::
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/bridgehead
)

# Package config + version file
configure_package_config_file(
    cmake/bridgeheadConfig.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/bridgeheadConfig.cmake
    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/bridgehead
)

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

install(FILES
    ${CMAKE_CURRENT_BINARY_DIR}/bridgeheadConfig.cmake
    ${CMAKE_CURRENT_BINARY_DIR}/bridgeheadConfigVersion.cmake
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/bridgehead
)
