cmake_minimum_required(VERSION 3.21)
project(venmic LANGUAGES CXX VERSION 7.2.3)

# +-------------------------------------------------------------------------------------------------------+
# | Library options                                                                                       |
# +-------------------------------------------------------------------------------------------------------+

option(venmic_addon           "Build as addon"                                               OFF)
option(venmic_server          "Build as rest server"                                          ON)

option(venmic_use_fill        "Enable usage of saucer-fill for compiling with libc++"        OFF) # Needed because of https://github.com/llvm/llvm-project/pull/94670
option(venmic_unexpected_hack "Fix std::unexpected ambiguity issues when compiling with zig" OFF)

option(venmic_prefer_remote    "Prefer remote packages over local packages"                   ON)

# +-------------------------------------------------------------------------------------------------------+
# | Addon and Rest-Server are mutually exclusive                                                          |
# +-------------------------------------------------------------------------------------------------------+

if (venmic_addon)
    set(venmic_server OFF)
endif()

if (venmic_server)
    set(venmic_addon OFF)
endif()

# +-------------------------------------------------------------------------------------------------------+
# | Sync `CPM_DOWNLOAD_ALL` with `venmic_prefer_remote`                                                   |
# +-------------------------------------------------------------------------------------------------------+

if (venmic_prefer_remote)
    message(STATUS "[venmic] Avoiding local packages as 'venmic_prefer_remote' is ON")
endif()

set(CPM_DOWNLOAD_ALL ${venmic_prefer_remote})

# +-------------------------------------------------------------------------------------------------------+
# | Sync `rohrkabel_should_install` with `venmic_use_fill`                                                |
# +-------------------------------------------------------------------------------------------------------+

if (venmic_use_fill)
    set(rohrkabel_should_install OFF)
else()
    set(rohrkabel_should_install ON)
endif()

# +-------------------------------------------------------------------------------------------------------+
# | CMake options                                                                                         |
# +-------------------------------------------------------------------------------------------------------+

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# +-------------------------------------------------------------------------------------------------------+
# | Create library                                                                                        |
# +-------------------------------------------------------------------------------------------------------+

add_library(${PROJECT_NAME})
add_library(vencord::venmic ALIAS ${PROJECT_NAME})

target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 23 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON)

if (PROJECT_IS_TOP_LEVEL AND NOT CMAKE_JS_VERSION)
    target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic -Werror -pedantic -pedantic-errors -Wfatal-errors)
endif()

if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    target_compile_options(${PROJECT_NAME} PUBLIC -Wno-attributes=vc::)
else()
    target_compile_options(${PROJECT_NAME} PUBLIC -Wno-unknown-attributes)
endif()

target_compile_options(${PROJECT_NAME} PRIVATE -Wno-missing-field-initializers -Wno-cast-function-type)

# +-------------------------------------------------------------------------------------------------------+
# | Add source files                                                                                      |
# +-------------------------------------------------------------------------------------------------------+

file(GLOB src "src/*.cpp")
target_sources(${PROJECT_NAME} PRIVATE ${src})

# +-------------------------------------------------------------------------------------------------------+
# | Include "include" folder                                                                              |
# +-------------------------------------------------------------------------------------------------------+

target_include_directories(${PROJECT_NAME} PUBLIC  "include")
target_include_directories(${PROJECT_NAME} PRIVATE "include/vencord" "private")

# +-------------------------------------------------------------------------------------------------------+
# | Setup compile definitions                                                                             |
# +-------------------------------------------------------------------------------------------------------+

target_compile_definitions(${PROJECT_NAME} PUBLIC VENMIC_VERSION="${PROJECT_VERSION}")

# +-------------------------------------------------------------------------------------------------------+
# | Setup precompiled headers                                                                             |
# +-------------------------------------------------------------------------------------------------------+

if (venmic_unexpected_hack)
    target_precompile_headers(${PROJECT_NAME} PUBLIC "cmake/toolchain/zig.fix.hpp")
endif()

# +-------------------------------------------------------------------------------------------------------+
# | Setup Dependencies                                                                                    |
# +-------------------------------------------------------------------------------------------------------+

include("cmake/cpm.cmake")

CPMFindPackage(
  NAME           rohrkabel
  VERSION        13.1.1
  GIT_REPOSITORY "https://github.com/Curve/rohrkabel"
  OPTIONS        "rohrkabel_install ${rohrkabel_should_install}"
)

CPMFindPackage(
  NAME           channel
  VERSION        4.0.0
  GIT_REPOSITORY "https://github.com/Curve/channel"
)

CPMFindPackage(
  NAME           glaze
  VERSION        7.9.1
  GIT_REPOSITORY "https://github.com/stephenberry/glaze"
)

CPMFindPackage(
  NAME           spdlog
  VERSION        1.17.0
  GIT_REPOSITORY "https://github.com/gabime/spdlog"
)

target_link_libraries(${PROJECT_NAME} PUBLIC cr::rohrkabel cr::channel glaze::glaze spdlog::spdlog)

# +-------------------------------------------------------------------------------------------------------+
# | Custom Find-Package configurations                                                                    |
# +-------------------------------------------------------------------------------------------------------+

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# +-------------------------------------------------------------------------------------------------------+
# | Link PulseAudio                                                                                       |
# +-------------------------------------------------------------------------------------------------------+

find_package(PulseAudio)
target_link_libraries(${PROJECT_NAME} PUBLIC PulseAudio::PulseAudio)

# +-------------------------------------------------------------------------------------------------------+
# | Setup Rest Server                                                                                     |
# +-------------------------------------------------------------------------------------------------------+

if (venmic_server)
    add_subdirectory(server)
endif()

# +-------------------------------------------------------------------------------------------------------+
# | Setup Node Addon                                                                                      |
# +-------------------------------------------------------------------------------------------------------+

if (venmic_addon AND NOT CMAKE_JS_VERSION)
    message(FATAL_ERROR "[venmic] Please build the addon using cmake-js")
endif()

if (venmic_addon)
    add_subdirectory(addon)
endif()

# +-------------------------------------------------------------------------------------------------------+
# | Setup saucer-fill                                                                                     |
# +-------------------------------------------------------------------------------------------------------+

if (NOT venmic_use_fill)
    return()
endif()

CPMFindPackage(
  NAME           saucer-fill
  VERSION        1.3.0
  GIT_REPOSITORY "https://github.com/saucer/fill"
  OPTIONS        "fill_namespace std" "fill_silent ON"
)

target_link_libraries(rohrkabel       PUBLIC saucer::fill)
target_link_libraries(${PROJECT_NAME} PUBLIC saucer::fill)
