cmake_minimum_required(VERSION 3.16)
project(joyinside)

set(CMAKE_POLICY_VERSION_MINIMUM 3.5)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_definitions(-DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_DEBUG)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Debug)
endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0")

option(LWS_WITH_TLS "Build with TLS support" ON)
option(LWS_WITH_MINIMAL_EXAMPLES "Build with examples" OFF)
option(JOYINSIDE_BUILD_DEMO "Build joyinside_demo executable" ON)

# Disable test suites of vendored deps globally. Some subprojects include(CTest),
# which defaults BUILD_TESTING=ON; opus then OR's that into OPUS_BUILD_TESTING and
# builds its test_opus_* executables, which try to link the dynamic loader
# (/lib/ld-linux-aarch64.so.1) and break the cross-link. We only need the libs.
set(BUILD_TESTING OFF CACHE BOOL "Disable vendored test suites" FORCE)

set(LWS_WITHOUT_TESTAPPS ON CACHE BOOL "Don't build the libwebsocket-test-apps")
set(LWS_WITH_STATIC ON CACHE BOOL "Build the static version of the library")
set(LWS_WITH_SHARED OFF CACHE BOOL "Do not build the shared version of the library")
set(YYJSON_BUILD_TESTS OFF CACHE BOOL "Disable yyjson tests" FORCE)
set(YYJSON_BUILD_FUZZER OFF CACHE BOOL "Disable yyjson fuzzer" FORCE)
set(YYJSON_BUILD_MISC OFF CACHE BOOL "Disable yyjson misc tools" FORCE)
set(YYJSON_BUILD_DOC OFF CACHE BOOL "Disable yyjson docs" FORCE)
set(YYJSON_INSTALL OFF CACHE BOOL "Disable yyjson install target" FORCE)

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/JoyinsideThreads.cmake")
joyinside_setup_threads()

set(GFLAGS_BUILD_TESTING OFF CACHE BOOL "" FORCE)
set(GFLAGS_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
set(GFLAGS_BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE)
set(GFLAGS_INSTALL_HEADERS OFF CACHE BOOL "" FORCE)

add_subdirectory(thirdparty/libwebsockets)
add_subdirectory(thirdparty/spdlog)
add_subdirectory(thirdparty/yyjson)

# libopus (bundled)
set(OPUS_BUILD_SHARED_LIBRARY OFF CACHE BOOL "" FORCE)
set(OPUS_BUILD_TESTING OFF CACHE BOOL "" FORCE)
set(OPUS_BUILD_PROGRAMS OFF CACHE BOOL "" FORCE)
set(OPUS_INSTALL_PKG_CONFIG_MODULE OFF CACHE BOOL "" FORCE)
set(OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF CACHE BOOL "" FORCE)
# Luckfox Aura (aarch64 Linux): fixed CPU, no runtime feature detection needed.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux"
   AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|ARM64)$")
    set(OPUS_PRESUME_NEON ON CACHE BOOL "" FORCE)
    set(OPUS_MAY_HAVE_NEON OFF CACHE BOOL "" FORCE)
endif()
add_subdirectory(thirdparty/opus)

# speexdsp resampler (bundled, minimal CMakeLists in thirdparty/speexdsp)
add_subdirectory(thirdparty/speexdsp)
add_subdirectory(thirdparty/gflags)

# libcurl / OpenSSL: not vendored in thirdparty; use system libraries.
find_package(CURL REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(ALSA REQUIRED)
joyinside_setup_threads()

set(SRC_LIST
    src/app_config.cpp
    src/joyinside_log.cpp
    src/stats_monitor.cpp
    src/audio_capturer.cpp
    src/audio_pcm_dumper.cpp
    src/opus_codec.cpp
    src/audio_player.cpp
    src/ws_sender.cpp
    src/event_loop.cpp
    src/application.cpp
    src/audiobook/audiobook_downloader.cpp
    src/audiobook/audiobook_mp3_decoder.cpp
    src/audiobook/audiobook_session.cpp
    joyinside_ws_client/joyinside_utils.cpp
    joyinside_ws_client/joyinside_curl_share.cpp
    joyinside_ws_client/joyinside_http_utils.cpp
    joyinside_ws_client/joyinside_auth.cpp
    joyinside_ws_client/joyinside_ws_client.cpp
)

# Static library: thirdparty deps are linked into the final executable.
add_library(joyinside STATIC ${SRC_LIST})

target_include_directories(
    joyinside
    PUBLIC
        .
        thirdparty/spdlog/include
        thirdparty/libwebsockets/include
        joyinside_ws_client
        src
        thirdparty/minimp3
)

target_link_libraries(
    joyinside
    PUBLIC
        Threads::Threads
        websockets
        spdlog
        yyjson
        CURL::libcurl
        OpenSSL::SSL
        OpenSSL::Crypto
        Opus::opus
        ALSA::ALSA
        speexdsp_resampler
        gflags::gflags
)

if(UNIX AND NOT APPLE)
    target_link_libraries(joyinside PUBLIC dl m)
endif()

if(JOYINSIDE_BUILD_DEMO)
    add_executable(joyinside_demo src/main.cpp)
    target_link_libraries(joyinside_demo PRIVATE joyinside)
    install(TARGETS joyinside_demo RUNTIME DESTINATION bin)
endif()
