cmake_minimum_required(
    VERSION 3.22
    FATAL_ERROR
)

if(POLICY CMP0156)
    cmake_policy(
        SET
        CMP0156
        NEW
    )
endif()

if(POLICY CMP0179)
    cmake_policy(
        SET
        CMP0179
        NEW
    )
endif()

# VCPKG cmake
# -DCMAKE_TOOLCHAIN_FILE=/opt/workspace/vcpkg/scripts/buildsystems/vcpkg.cmake
# .. Needed libs are in file vcpkg.json Windows required libs: .\vcpkg install
# --triplet x64-windows asio pugixml spdlog curl protobuf parallel-hashmap
# magic-enum mio luajit libmariadb mbedtls abseil bshoshany-thread-pool

if(DEFINED ENV{VCPKG_ROOT}
   AND NOT
       DEFINED
       CMAKE_TOOLCHAIN_FILE
)
    set(CMAKE_TOOLCHAIN_FILE
        "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
        CACHE STRING ""
    )
endif()

if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET}
   AND NOT
       DEFINED
       VCPKG_TARGET_TRIPLET
)
    set(VCPKG_TARGET_TRIPLET
        "$ENV{VCPKG_DEFAULT_TRIPLET}"
        CACHE STRING ""
    )
endif()

set(VCPKG_FEATURE_FLAGS
    "versions"
)
if(NOT
   DEFINED
   VCPKG_BUILD_TYPE
)
    set(VCPKG_BUILD_TYPE
        "release"
    )
endif()
set(VCPKG_BUILD_TYPE
    "${VCPKG_BUILD_TYPE}"
    CACHE STRING "vcpkg build type"
)
set(CMAKE_EXPORT_COMPILE_COMMANDS
    ON
)

set(VCPKG_MANIFEST_FEATURES
    "${VCPKG_MANIFEST_FEATURES}"
    CACHE STRING "vcpkg manifest features"
)

# *****************************************************************************
# Project canary
# *****************************************************************************
if(CMAKE_BUILD_TYPE
   STREQUAL
   "Debug"
)
    project(
        canary-debug
        LANGUAGES CXX
    )
else()
    project(
        canary
        LANGUAGES CXX
    )
endif()

# *****************************************************************************
# Append cmake search path
# *****************************************************************************
list(
    APPEND
    CMAKE_MODULE_PATH
    ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
)

# Configure build options for compatibility with commodity CPUs
if(NOT MSVC)
    if(CMAKE_SYSTEM_PROCESSOR
       MATCHES
       "x86_64|AMD64"
    )
        set(CMAKE_CXX_FLAGS
            "${CMAKE_CXX_FLAGS} -march=x86-64 -mtune=generic -mno-avx -mno-sse4"
        )
        set(CMAKE_C_FLAGS
            "${CMAKE_C_FLAGS} -march=x86-64 -mtune=generic -mno-avx -mno-sse4"
        )
    elseif(
        CMAKE_SYSTEM_PROCESSOR
        MATCHES
        "arm64|aarch64"
    )
        # ARM64 specific flags for compatibility
        if(APPLE)
            set(CMAKE_CXX_FLAGS
                "${CMAKE_CXX_FLAGS} -mcpu=apple-a14"
            )
            set(CMAKE_C_FLAGS
                "${CMAKE_C_FLAGS} -mcpu=apple-a14"
            )
        else()
            # Generic ARM64 flags for Linux/other systems
            set(CMAKE_CXX_FLAGS
                "${CMAKE_CXX_FLAGS} -march=armv8-a -mtune=generic"
            )
            set(CMAKE_C_FLAGS
                "${CMAKE_C_FLAGS} -march=armv8-a -mtune=generic"
            )
        endif()
    endif()
endif()

# *****************************************************************************
# Include cmake tools
# *****************************************************************************
include(MessageColors)
include(LoggingHelper)

# *****************************************************************************
# Options
# *****************************************************************************
option(
    OPTIONS_ENABLE_CCACHE
    "Enable ccache"
    OFF
)
option(
    OPTIONS_ENABLE_SCCACHE
    "Use sccache to speed up compilation process"
    OFF
)
option(
    OPTIONS_ENABLE_IPO
    "Check and Enable interprocedural optimization (IPO/LTO)"
    ON
)
option(
    FEATURE_METRICS
    "Enable metrics feature"
    OFF
)

# *****************************************************************************
# Options Code
# *****************************************************************************

if(FEATURE_METRICS)
    log_option_enabled("metrics")
else()
    log_option_disabled("metrics")
endif()

# === CCACHE ===
if(OPTIONS_ENABLE_CCACHE)
    find_program(CCACHE ccache)
    if(CCACHE)
        log_option_enabled("ccache")
        set(CMAKE_CXX_COMPILER_LAUNCHER
            ${CCACHE}
        )
    else()
        log_option_disabled("ccache")
    endif()
endif()

# === SCCACHE ===
if(OPTIONS_ENABLE_SCCACHE)
    find_program(SCCACHE_PATH sccache)
    if(SCCACHE_PATH)
        log_option_enabled("sccache")
        set(CMAKE_C_COMPILER_LAUNCHER
            ${SCCACHE_PATH}
        )
        set(CMAKE_CXX_COMPILER_LAUNCHER
            ${SCCACHE_PATH}
        )
    else()
        log_option_disabled("sccache")
    endif()
endif()

# *****************************************************************************
# Options for Targets
# *****************************************************************************
option(
    CANARY_BUILD_TESTS
    "Build unit tests"
    OFF
)
option(
    CANARY_BUILD_SERVER
    "Build server executable"
    ON
)
if(CANARY_BUILD_TESTS)
    if(NOT
       "tests"
       IN_LIST
       VCPKG_MANIFEST_FEATURES
    )
        message(
            FATAL_ERROR
                "CANARY_BUILD_TESTS requires the vcpkg manifest feature 'tests'. Use a test preset or configure with -DVCPKG_MANIFEST_FEATURES=tests."
        )
    endif()
    enable_testing()
endif()

# *****************************************************************************
# Add project
# *****************************************************************************
add_subdirectory(src)
add_subdirectory(tests)
