cmake_minimum_required(VERSION 3.5)
project (SecretsProvisioningLibrary)
set(CMAKE_CXX_STANDARD 17)

add_definitions (-DPLATFORM_UNIX)

set (CMAKE_PROJECT_TARGET SecretsProvisioningLibrary)
project (Linux${CMAKE_PROJECT_TARGET})

# 1. Read version from file 
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/version.txt" VERSION_CONTENT)
string(STRIP "${VERSION_CONTENT}" VERSION_CONTENT)
string(REPLACE "." ";" VERSION_PARTS ${VERSION_CONTENT})

list(GET VERSION_PARTS 0 SECRETS_LIB_VERSION_MAJOR)
list(GET VERSION_PARTS 1 SECRETS_LIB_VERSION_MINOR)
list(GET VERSION_PARTS 2 SECRETS_LIB_VERSION_PATCH)

set(SECRETS_LIB_VERSION "${SECRETS_LIB_VERSION_MAJOR}.${SECRETS_LIB_VERSION_MINOR}.${SECRETS_LIB_VERSION_PATCH}")

# Propagate version vars to subdirectories (DynamicSecretsProvisioningLibrary needs
# these for SOVERSION on the shared library; see Fedora SOVERSION guideline).
set(SECRETS_LIB_VERSION       "${SECRETS_LIB_VERSION}"       CACHE INTERNAL "")
set(SECRETS_LIB_VERSION_MAJOR "${SECRETS_LIB_VERSION_MAJOR}" CACHE INTERNAL "")
set(SECRETS_LIB_VERSION_MINOR "${SECRETS_LIB_VERSION_MINOR}" CACHE INTERNAL "")
set(SECRETS_LIB_VERSION_PATCH "${SECRETS_LIB_VERSION_PATCH}" CACHE INTERNAL "")

# 2. Generate version header
configure_file(
  ${CMAKE_CURRENT_SOURCE_DIR}/Linux/Version.h.in
  ${CMAKE_CURRENT_BINARY_DIR}/generated/Version.h
  @ONLY
)


# Try to find Tss2
find_path(TSS2_INCLUDE_DIR NAMES tss2 PATHS ${SYSTEM_LIBRARY_PREFIX}/usr/local/include ${SYSTEM_LIBRARY_PREFIX}/usr/include NO_DEFAULT_PATH)

# Invalidate cache to force cmake to lookup the libraries again
set (TSS2_ESYS TSS2_ESYS-NOTFOUND)
set (TSS2_SYS TSS2_SYS-NOTFOUND)
set (TSS2_MU TSS2_MU-NOTFOUND)
set (TSS2_TCTI_DEVICE TSS2_TCTI_DEVICE-NOTFOUND)
set (TSS2_RC TSS2_RC-NOTFOUND)

find_library(TSS2_ESYS names tss2-esys PATHS /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/ NO_DEFAULT_PATH)
find_library(TSS2_SYS names tss2-sys PATHS /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/  NO_DEFAULT_PATH)
find_library(TSS2_MU NAMES tss2-mu PATHS /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/  NO_DEFAULT_PATH)
find_library(TSS2_TCTI_DEVICE NAMES tss2-tcti-device PATHS /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/  NO_DEFAULT_PATH)
find_library(TSS2_RC NAMES tss2-rc PATHS /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/  NO_DEFAULT_PATH)
# find_library(TSS2_ESYS names libtss2-esys.a tss2-esys PATHS /usr/lib/x86_64-linux-gnu/  NO_DEFAULT_PATH)
# find_library(TSS2_SYS names libtss2-sys.a tss2-sys PATHS /usr/lib/x86_64-linux-gnu/ NO_DEFAULT_PATH)
# find_library(TSS2_MU NAMES libtss2-mu.a tss2-mu PATHS /usr/lib/x86_64-linux-gnu/ NO_DEFAULT_PATH)
# find_library(TSS2_TCTI_DEVICE NAMES libtss2-tcti-device.a tss2-tcti-device PATHS /usr/lib/x86_64-linux-gnu/ NO_DEFAULT_PATH)
# find_library(TSS2_RC NAMES libtss2-rc.a tss2-rc PATHS /usr/lib/x86_64-linux-gnu/ NO_DEFAULT_PATH)

# set(TSS2_LIBRARIES ${TSS2_RC} ${TSS2_ESYS} ${TSS2_SYS} ${TSS2_MU} ${TSS2_TCTI_DEVICE} dl)
set(TSS2_LIBRARIES ${TSS2_ESYS} ${TSS2_TCTI_DEVICE} ${TSS2_RC} ${TSS2_MU} ${TSS2_SYS} dl)

set(TSS2_INCLUDE_DIRS ${TSS2_INCLUDE_DIR})

set(ATTESTATION_INCLUDE_DIRS external/attestation/)

# include(FetchContent)
# FetchContent_Declare(
#     tss2
#     URL https://github.com/tpm2-software/tpm2-tss
#     GIT_TAG 3.2.0)
# FetchContent_MakeAvailable(tss2)

# Find Boost
find_package(Boost REQUIRED)

# find_package(Tss2 REQUIRED)
# 3. *** CRITICAL CHANGE: Add this line FIRST before any other includes ***
include_directories(
  ${CMAKE_CURRENT_BINARY_DIR}/generated  # Generated headers first
  ${CMAKE_CURRENT_SOURCE_DIR}            # Source directory for other headers
  ${TSS2_INCLUDE_DIRS} 
  ${Boost_INCLUDE_DIRS} 
  ${ATTESTATION_INCLUDE_DIRS}
)
# Prefer static OpenSSL when libcrypto.a is actually available (e.g., Azure
# Linux / Mariner ship static libs). On distros that ship only shared libs
# (e.g., Fedora's openssl-devel), fall back to dynamic linking  the runtime
# loader resolves OpenSSL symbols. This replaces the older unconditional
# `set(OPENSSL_USE_STATIC_LIBS TRUE)` which would cause find_package(OpenSSL)
# to fail on Fedora-style systems.
find_library(_openssl_static_crypto NAMES libcrypto.a
    HINTS /usr/lib64 /usr/lib NO_DEFAULT_PATH)
if(_openssl_static_crypto)
    set(OPENSSL_USE_STATIC_LIBS TRUE)
endif()
mark_as_advanced(_openssl_static_crypto)
find_package(OpenSSL REQUIRED)

file(GLOB SOURCES "*.cpp" "Linux/*.cpp" "CvmHelper/src/*.cpp")

# nlohmann/json: prefer system package (Fedora ships nlohmann-json-devel), fall
# back to FetchContent for build environments without it (e.g., the OneBranch
# Azure Linux image used for PMC builds). Fedora guidelines forbid bundling
# system libraries: index.adoc Bundling, Build Time Network Access.
find_package(nlohmann_json QUIET)
if(NOT nlohmann_json_FOUND)
    include(FetchContent)
    FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz)
    FetchContent_MakeAvailable(json)
endif()

find_package(PkgConfig REQUIRED)
pkg_check_modules(SYSTEMD libsystemd)

if(NOT SYSTEMD_FOUND)
    # Fallback for older or different distributions
    find_path(SYSTEMD_INCLUDE_DIRS systemd/sd-journal.h)
    find_library(SYSTEMD_LIBRARIES systemd)
    if(SYSTEMD_INCLUDE_DIRS AND SYSTEMD_LIBRARIES)
        set(SYSTEMD_FOUND TRUE)
    endif()
endif()

if(SYSTEMD_FOUND)
    include_directories(${SYSTEMD_INCLUDE_DIRS})
    add_definitions(-DUSE_SYSTEMD)
else()
    message(WARNING "systemd development files not found - falling back to stdout logging only")
endif()

add_compile_options(-Wall -Wextra -Wpedantic)

add_library(${CMAKE_PROJECT_TARGET} STATIC ${SOURCES})
target_link_libraries(${CMAKE_PROJECT_TARGET} ${SYSTEMD_LIBRARIES})
target_link_libraries(${CMAKE_PROJECT_TARGET} ${TSS2_LIBRARIES})
#target_link_libraries(${CMAKE_PROJECT_TARGET} ${CRYPTO_LIB})
target_link_libraries(${CMAKE_PROJECT_TARGET} OpenSSL::Crypto)
target_link_libraries(${CMAKE_PROJECT_TARGET} ${SSL_LIB})
target_link_libraries(${CMAKE_PROJECT_TARGET} pthread)
target_link_libraries(${CMAKE_PROJECT_TARGET} dl)
# target_link_libraries(${CMAKE_PROJECT_TARGET} tss2-mu)
target_link_libraries(${CMAKE_PROJECT_TARGET} nlohmann_json::nlohmann_json)
target_link_libraries(${CMAKE_PROJECT_TARGET} Boost::boost)
set_property(TARGET ${CMAKE_PROJECT_TARGET} PROPERTY POSITION_INDEPENDENT_CODE ON)

# NOTE: VERSION/SOVERSION on a STATIC archive has no effect; SOVERSION lives
# on the SHARED target in DynamicSecretsProvisioningLibrary/CMakeLists.txt.

# Prevent GoogleTest from installing its files into the package
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE)

# Enable CTest so `ctest` (the spec's %check / %ctest) discovers registered
# tests. Only the mock-safe tool tests register themselves (see
# azure-protected-secrets-tool/tests/CMakeLists.txt); the TPM-dependent suites
# do not, so they are skipped in the Fedora build chroot.
enable_testing()

add_subdirectory(SecretsProvsioningUT)
add_subdirectory(SecretsProvisioningFunctionalityTest)
add_subdirectory(DynamicSecretsProvisioningLibrary)
add_subdirectory(SecretsProvisioningSample)
add_subdirectory(azure-protected-secrets-tool)

# --- CPack: bundle shared library + CLI into one package ---
find_program(APT_PROGRAM apt)
find_program(RPM_PROGRAM rpm)

if(APT_PROGRAM)
    set(CPACK_GENERATOR "DEB")
    set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Microsoft Corp")
    set(CPACK_DEBIAN_PACKAGE_DEPENDS "libssl3t64, libtss2-esys-3.0.2-0t64, libtss2-sys1t64, libtss2-mu-4.0.1-0t64, libtss2-tcti-device0t64, libtss2-rc0t64")
    set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
elseif(RPM_PROGRAM)
    set(CPACK_GENERATOR "RPM")
    set(CPACK_RPM_PACKAGE_ARCHITECTURE "x86_64")
endif()

set(CPACK_PACKAGE_VERSION "${SECRETS_LIB_VERSION}")
set(CPACK_PACKAGE_CONTACT "")
set(CPACK_PACKAGE_NAME "azure-protected-vm-secrets")
set(CPACK_PACKAGE_DESCRIPTION "Shared library and CLI tool for the Azure Protected VM Secrets feature for CVMs")
set(CPACK_PACKAGE_VENDOR "Microsoft Corp")
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")

include(CPack)