cmake_minimum_required(VERSION 3.22)
cmake_policy(SET CMP0135 NEW)

project(smartbotic-crm
    VERSION 0.1.0
    DESCRIPTION "SmartBotic CRM System"
    LANGUAGES CXX
)

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

# Export compile commands for tooling
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Build options
option(ENABLE_SANITIZERS "Enable address and undefined behavior sanitizers" OFF)

# Compiler warnings - applied only to project targets, not dependencies
set(SMARTBOTIC_CXX_WARNINGS
    -Wall
    -Wextra
    -Wpedantic
    -Werror
    -Wno-unused-parameter
    -Wno-dangling-reference  # False positive in spdlog's bundled fmt with GCC 13+
)

# Sanitizers for debug builds
if(ENABLE_SANITIZERS)
    add_compile_options(-fsanitize=address,undefined)
    add_link_options(-fsanitize=address,undefined)
endif()

# ============================================================================
# System Dependencies
# Required packages: libspdlog-dev nlohmann-json3-dev
# ============================================================================
find_package(spdlog REQUIRED)
find_package(nlohmann_json REQUIRED)

# ============================================================================
# FetchContent Dependencies (latest versions)
# ============================================================================
include(FetchContent)

# cpp-httplib - Header-only HTTP library (always use latest)
FetchContent_Declare(
    httplib
    GIT_REPOSITORY https://github.com/yhirose/cpp-httplib.git
    GIT_TAG v0.30.1
)

# jwt-cpp - Header-only JWT library (no compatible system package)
FetchContent_Declare(
    jwt-cpp
    GIT_REPOSITORY https://github.com/Thalhammer/jwt-cpp.git
    GIT_TAG v0.7.1
)

message(STATUS "Fetching cpp-httplib...")
set(HTTPLIB_REQUIRE_OPENSSL ON CACHE BOOL "" FORCE)
set(HTTPLIB_COMPILE OFF CACHE BOOL "" FORCE)  # Header-only mode
FetchContent_MakeAvailable(httplib)

message(STATUS "Fetching jwt-cpp...")
set(JWT_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(JWT_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(JWT_EXTERNAL_PICOJSON OFF CACHE BOOL "" FORCE)  # Use bundled picojson
FetchContent_MakeAvailable(jwt-cpp)

# ============================================================================
# System gRPC and Protobuf (fast builds using system packages)
# Required packages: libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc
# ============================================================================
message(STATUS "Using system gRPC and Protobuf...")
find_package(Protobuf REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GRPC REQUIRED IMPORTED_TARGET grpc++)

# Find reflection library (no pkg-config file in Ubuntu package)
find_library(GRPC_REFLECTION_LIB grpc++_reflection REQUIRED)
message(STATUS "  grpc++_reflection: ${GRPC_REFLECTION_LIB}")

# Create imported target for reflection library
add_library(grpc_reflection SHARED IMPORTED)
set_target_properties(grpc_reflection PROPERTIES
    IMPORTED_LOCATION ${GRPC_REFLECTION_LIB}
    INTERFACE_LINK_LIBRARIES PkgConfig::GRPC
)

# Find protoc and grpc_cpp_plugin executables
find_program(PROTOC_EXECUTABLE protoc REQUIRED)
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin REQUIRED)
message(STATUS "  protoc: ${PROTOC_EXECUTABLE}")
message(STATUS "  grpc_cpp_plugin: ${GRPC_CPP_PLUGIN}")

# libwebsockets via pkg-config (system library)
pkg_check_modules(LWS REQUIRED IMPORTED_TARGET libwebsockets)

# OpenSSL for HTTPS support and crypto operations (replaces libsodium)
find_package(OpenSSL REQUIRED)
message(STATUS "  OpenSSL version: ${OPENSSL_VERSION}")

# ============================================================================
# Project Subdirectories
# ============================================================================

add_subdirectory(common)
add_subdirectory(proto)
add_subdirectory(database)
add_subdirectory(webserver)
add_subdirectory(webui)

# ============================================================================
# Summary
# ============================================================================

message(STATUS "")
message(STATUS "SmartBotic CRM Configuration Summary")
message(STATUS "=====================================")
message(STATUS "Version:           ${PROJECT_VERSION}")
message(STATUS "C++ Standard:      ${CMAKE_CXX_STANDARD}")
message(STATUS "Build Type:        ${CMAKE_BUILD_TYPE}")
message(STATUS "Compiler:          ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "Sanitizers:        ${ENABLE_SANITIZERS}")
message(STATUS "")
