# Smartbotic Database
# Standalone document database with gRPC API

cmake_minimum_required(VERSION 3.20)

# Read version from VERSION file
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" SMARTBOTIC_DB_VERSION)
string(STRIP "${SMARTBOTIC_DB_VERSION}" SMARTBOTIC_DB_VERSION)

# v2.8.0 — build provenance. BUILD_GIT_COMMIT was computed by build.sh and passed
# as a Docker --build-arg since v2.4, and Dockerfile.build declared the ARG, but
# nothing ever consumed it: unlike BUILD_VERSION it was never promoted to an ENV,
# so no commit reached the binary or the package. `dpkg -s` showed a version and
# nothing else, which is the same triage gap that made --version useless for the
# whole 2.x line before v2.4.1.
#
# Prefer the environment (set by the Docker build), fall back to asking git, and
# accept "unknown" rather than failing a build outside a checkout.
if(DEFINED ENV{BUILD_GIT_COMMIT})
    set(SMARTBOTIC_DB_GIT_COMMIT "$ENV{BUILD_GIT_COMMIT}")
else()
    execute_process(
        COMMAND git -C "${CMAKE_CURRENT_SOURCE_DIR}" rev-parse --short HEAD
        OUTPUT_VARIABLE SMARTBOTIC_DB_GIT_COMMIT
        OUTPUT_STRIP_TRAILING_WHITESPACE
        ERROR_QUIET)
endif()
if(NOT SMARTBOTIC_DB_GIT_COMMIT)
    set(SMARTBOTIC_DB_GIT_COMMIT "unknown")
endif()

# Detect standalone vs embedded mode
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    # Building as standalone project
    project(smartbotic-database VERSION ${SMARTBOTIC_DB_VERSION} LANGUAGES CXX C)
    set(SMARTBOTIC_DB_STANDALONE ON)
else()
    # Building as embedded submodule
    set(SMARTBOTIC_DB_STANDALONE OFF)
endif()

# Shared libraries for standalone (packaging), static for embedded (submodule)
option(BUILD_SHARED_LIBS "Build shared libraries" ${SMARTBOTIC_DB_STANDALONE})

# C++ settings
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Build options
option(SMARTBOTIC_DB_BUILD_CLIENT "Build the database client library" ON)
option(SMARTBOTIC_DB_BUILD_SERVICE "Build the database service executable" ${SMARTBOTIC_DB_STANDALONE})

# Find required packages
find_package(Protobuf REQUIRED)
find_package(gRPC CONFIG QUIET)
if(NOT gRPC_FOUND)
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(GRPC REQUIRED grpc++)
endif()
find_package(nlohmann_json 3.2.0 QUIET)
if(NOT nlohmann_json_FOUND)
    find_package(PkgConfig QUIET)
    if(PKG_CONFIG_FOUND)
        pkg_check_modules(NLOHMANN_JSON QUIET nlohmann_json)
    endif()
    if(NOT nlohmann_json_FOUND AND NOT NLOHMANN_JSON_FOUND)
        # Not available on system - parent project or FetchContent provides it
        if(NOT TARGET nlohmann_json::nlohmann_json)
            include(FetchContent)
            FetchContent_Declare(
                nlohmann_json
                GIT_REPOSITORY https://github.com/nlohmann/json.git
                GIT_TAG        v3.11.3
                GIT_SHALLOW    TRUE
            )
            set(JSON_BuildTests OFF CACHE BOOL "" FORCE)
            set(JSON_Install OFF CACHE BOOL "" FORCE)
            FetchContent_MakeAvailable(nlohmann_json)
        endif()
    elseif(NLOHMANN_JSON_FOUND AND NOT TARGET nlohmann_json::nlohmann_json)
        add_library(nlohmann_json::nlohmann_json INTERFACE IMPORTED)
        set_target_properties(nlohmann_json::nlohmann_json PROPERTIES
            INTERFACE_INCLUDE_DIRECTORIES "${NLOHMANN_JSON_INCLUDE_DIRS}"
        )
    endif()
endif()

# Find spdlog
find_package(spdlog QUIET)
if(NOT spdlog_FOUND)
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(SPDLOG REQUIRED spdlog)
endif()

# Optional: systemd support
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
    pkg_check_modules(SYSTEMD QUIET libsystemd)
endif()

# Proto compilation
add_subdirectory(proto)

# Client library
if(SMARTBOTIC_DB_BUILD_CLIENT)
    add_subdirectory(client)
endif()

# Service executable
if(SMARTBOTIC_DB_BUILD_SERVICE)
    add_subdirectory(service)
endif()

# CLI admin tool (standalone build only)
option(SMARTBOTIC_DB_BUILD_CLI "Build CLI admin tool" ${SMARTBOTIC_DB_STANDALONE})
if(SMARTBOTIC_DB_BUILD_CLI)
    add_subdirectory(cli)
endif()

# Tests (standalone build only)
option(SMARTBOTIC_DB_BUILD_TESTS "Build unit/integration tests" ${SMARTBOTIC_DB_STANDALONE})
if(SMARTBOTIC_DB_BUILD_TESTS)
    add_subdirectory(tests)
endif()

# Print configuration summary
if(SMARTBOTIC_DB_STANDALONE)
    message(STATUS "")
    message(STATUS "Smartbotic Database ${SMARTBOTIC_DB_VERSION}")
    message(STATUS "  Build client library: ${SMARTBOTIC_DB_BUILD_CLIENT}")
    message(STATUS "  Build service:        ${SMARTBOTIC_DB_BUILD_SERVICE}")
    message(STATUS "  Build tests:          ${SMARTBOTIC_DB_BUILD_TESTS}")
    message(STATUS "  Systemd support:      ${SYSTEMD_FOUND}")
    message(STATUS "")
endif()
