# cmake-format: off
# Copyright (c) 2025-2026, Intel Corporation
#
# SPDX-License-Identifier: BSD-3-Clause
# cmake-format: on

cmake_minimum_required(VERSION 3.16)
cmake_policy(VERSION 3.16)
project(imb-provider)

# Source files
set(PROV_COMMON_SRC e_prov.c prov_evp.c)
set(PROV_SRC prov_init.c prov_ciphers.c prov_bio.c)
set(PROV_SW_IPSEC_SRC prov_sw_gcm.c prov_sha.c prov_sw_sha.c prov_sw_ipsec_inf.c)
set(PROV_PQC_SRC prov_sw_pqc.c prov_mldsa.c prov_mlkem.c)
set(PROV_SW_ASYNC prov_sw_submit.c prov_sw_freelist.c prov_sw_polling.c prov_sw_queue.c prov_sw_init.c prov_events.c prov_sw_hmac_sha.c prov_hmac_sha.c prov_sw_aes_cfb.c prov_aes_cfb.c prov_aes_ccm.c prov_sw_ccm.c prov_sm4.c prov_chacha20_poly1305.c prov_sw_chacha20_poly1305.c prov_sw_chacha20.c prov_chacha20.c prov_poly1305.c prov_sw_poly1305.c)
set(IPSEC_SRC ${CMAKE_SOURCE_DIR}/../../lib/intel-ipsec-mb.h)
include_directories(${CMAKE_SOURCE_DIR}/../../lib)

# Add the library target
add_library(imb-provider SHARED ${PROV_COMMON_SRC} ${PROV_SRC} ${PROV_SW_IPSEC_SRC} ${PROV_PQC_SRC} ${PROV_SW_ASYNC} ${IPSEC_SRC})

# Compiler flags
set(CFLAGS_COMMON "-Wall -Wformat -Wformat-security -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong")

if(OPENSSL_INSTALL_DIR)
  if(OPENSSL_INSTALL_DIR MATCHES "^~")
    string(SUBSTRING ${OPENSSL_INSTALL_DIR} 2 -1 OPENSSL_INSTALL_DIR)
    file(TO_CMAKE_PATH "$ENV{HOME}/${OPENSSL_INSTALL_DIR}" OPENSSL_INSTALL_DIR)
  endif()
  set(ENV{LD_LIBRARY_PATH} "${OPENSSL_INSTALL_DIR}/usr/local/:$ENV{LD_LIBRARY_PATH}")
  set(ENV{PATH} "${OPENSSL_INSTALL_DIR}/usr/local/bin:$ENV{PATH}")
  set(LIBDIR "${OPENSSL_INSTALL_DIR}/lib64/ossl-modules")
  set(CFLAGS_OPENSSL_3 "-DOPENSSL_SUPPRESS_DEPRECATED")
  set(OPENSSL_LIB "-Wl,-rpath,${OPENSSL_INSTALL_DIR}/lib64 -L${OPENSSL_INSTALL_DIR}/lib64 -lcrypto")
  set(INCLUDES_OPENSSL "-I${OPENSSL_INSTALL_DIR}/usr/local")
  install(TARGETS imb-provider DESTINATION ${LIBDIR})
else() 
  set(OPENSSL_LIB "-lcrypto")
  set(CFLAGS_OPENSSL_3 "-DOPENSSL_SUPPRESS_DEPRECATED")
endif()

if(WITH_IPSEC_BUILD_DIR)
  if(WITH_IPSEC_BUILD_DIR MATCHES "^~")
    string(SUBSTRING ${WITH_IPSEC_BUILD_DIR} 2 -1 WITH_IPSEC_BUILD_DIR)
    file(TO_CMAKE_PATH "$ENV{HOME}/${WITH_IPSEC_BUILD_DIR}" PROV_SW_IPSEC_MB_LIB)
    set(PROV_SW_IPSEC_MB_LIB "${PROV_SW_IPSEC_MB_LIB}/lib/libIPSec_MB.so")
  else()
    set(PROV_SW_IPSEC_MB_LIB "${WITH_IPSEC_BUILD_DIR}/lib/libIPSec_MB.so")
  endif()
  link_directories(${PROV_SW_IPSEC_MB_LIB})
  set_target_properties(imb-provider PROPERTIES LINK_FLAGS "-shared ${PROV_SW_IPSEC_MB_LIB}")
  target_link_libraries(imb-provider ${PROV_SW_IPSEC_MB_LIB})
endif()

if(WITH_IPSEC_INSTALL_DIR)
  if(WITH_IPSEC_INSTALL_DIR MATCHES "^~")
    string(SUBSTRING ${WITH_IPSEC_INSTALL_DIR} 2 -1 WITH_IPSEC_INSTALL_DIR)
    file(TO_CMAKE_PATH "$ENV{HOME}/${WITH_IPSEC_INSTALL_DIR}" WITH_IPSEC_INSTALL_DIR)
  endif()
  include_directories(${WITH_IPSEC_INSTALL_DIR}/usr/include)
  set(INCLUDES_PROV_SW_IPSEC_MB "-I${WITH_IPSEC_INSTALL_DIR}/include")
  find_library(PROV_SW_IPSEC_MB_LIB NAMES IPSec_MB PATHS ${WITH_IPSEC_INSTALL_DIR})
endif()

# Output settings
include_directories(${INCLUDES_OPENSSL} ${INCLUDES_PROV_SW_IPSEC_MB})
add_definitions(${CFLAGS_COMMON} ${CFLAGS_OPENSSL_3})
set_target_properties(imb-provider PROPERTIES INSTALL_RPATH "${OPENSSL_INSTALL_DIR}/usr/local/lib64/")
link_libraries(${OPENSSL_LIB} ${PROV_SW_IPSEC_MB_LIB})

# Set empty prefix
set(CMAKE_STATIC_LIBRARY_PREFIX "")
set(CMAKE_SHARED_LIBRARY_PREFIX "")

# Enable testing
enable_testing()

# Add test subdirectory
add_subdirectory(test)

# Copy imb-provider.so to test directory after build
add_custom_command(
  TARGET imb-provider
  POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy
    $<TARGET_FILE:imb-provider>
    ${CMAKE_CURRENT_BINARY_DIR}/test/
  COMMENT "Copying imb-provider.so to test directory"
)
