cmake_minimum_required(VERSION 3.20)
project(RadiantWave VERSION 0.1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# App version string shown at the top of the Home footer. Defaults to the
# project version; override at configure time with:
#   cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DAPP_VERSION="1.2.3"
set(APP_VERSION "${PROJECT_VERSION}" CACHE STRING
    "Version string shown in the Home footer (override at configure time)")

# API bearer key baked into the binary and sent as `Authorization: Bearer <key>`
# on every portal request. Leave empty to send no auth header. Never commit the
# real value — inject it at CI build time from a secret, e.g.:
#   cmake ... -DAPI_KEY="${{ secrets.PORTAL_API_KEY }}"
set(API_KEY "" CACHE STRING
    "Portal API key baked into the binary (leave empty to skip auth)")

find_package(SDL3 REQUIRED)
find_package(SDL3_ttf REQUIRED)
find_package(SDL3_image REQUIRED)
find_package(SDL3_mixer REQUIRED)
find_package(SDL3_net REQUIRED)
find_package(SQLite3 REQUIRED)
find_package(CURL REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(GTest REQUIRED)
include(GoogleTest)

# Network manager dependencies (Linux only)
if(UNIX AND NOT APPLE)
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(SDBUS REQUIRED libsystemd)
endif()

add_executable(radiantwave
    src/main.cpp
    src/page_manager.cpp
    src/home.cpp
    src/settings.cpp
    src/wifi_setup_page.cpp
    src/audio_settings_page.cpp
    src/audio/audio_manager.cpp
    src/audio/audio_downloader.cpp
    src/timezone_page.cpp
    src/timezone_helper.cpp
    src/log_viewer_page.cpp
    src/logger/logger.cpp
    src/keybind_manager.cpp
    src/provisioning.cpp
    src/network/nm_connection.cpp
    src/network/nm_device.cpp
    src/network/network_manager.cpp
    src/network/json.cpp
    src/network/api_client.cpp
    src/network/license_service.cpp
    src/network/license_status.cpp
    src/config/yaml_parser.cpp
    src/config/config_manager.cpp
    src/db/database_manager.cpp
    src/network/proclamation_sync.cpp
    src/proclamation_options_page.cpp
    src/email_address_page.cpp
    src/license_key_page.cpp
    src/license_blocked_page.cpp
    src/validation.cpp
    src/date_format.cpp
    src/date_format_page.cpp
    src/fibonacci_line_pattern.cpp
    src/scroller_streams.cpp
    src/scroller_page.cpp
    src/scramble/fibonacci_scrambler.cpp
)

target_compile_definitions(radiantwave PRIVATE
    APP_VERSION="${APP_VERSION}"
    API_KEY="${API_KEY}"
)

target_include_directories(radiantwave PRIVATE src)
target_link_libraries(radiantwave PRIVATE
    SDL3::SDL3
    SDL3_ttf::SDL3_ttf
    SDL3_image::SDL3_image
    SDL3_mixer::SDL3_mixer
    SDL3_net::SDL3_net
    SQLite3::SQLite3
    CURL::libcurl
    OpenSSL::Crypto
)

if(UNIX AND NOT APPLE)
    target_link_libraries(radiantwave PRIVATE ${SDBUS_LIBRARIES} resolv)
    target_include_directories(radiantwave PRIVATE ${SDBUS_INCLUDE_DIRS})
    target_compile_definitions(radiantwave PRIVATE HAS_DBUS=1)
endif()

install(TARGETS radiantwave RUNTIME DESTINATION bin)

add_executable(tests
    tests/test_page_manager.cpp
    tests/test_keybind_manager.cpp
    src/page_manager.cpp
    src/keybind_manager.cpp
)
target_include_directories(tests PRIVATE src)
target_link_libraries(tests PRIVATE SDL3::SDL3)

# Provisioning walkthrough logic tests (pure functions, no app linkage)
add_executable(test_provisioning
    tests/test_provisioning.cpp
)
target_include_directories(test_provisioning PRIVATE src)
target_link_libraries(test_provisioning PRIVATE SDL3::SDL3)

add_executable(test_assets
    tests/test_assets.cpp
)
target_include_directories(test_assets PRIVATE src)

# Network manager unit tests
add_executable(test_network_unit
    tests/network/test_nm_connection.cpp
    src/network/nm_connection.cpp
)
target_include_directories(test_network_unit PRIVATE src)
target_link_libraries(test_network_unit PRIVATE GTest::gtest_main)

# Access point parsing unit tests (pure mapping; the sd-bus reads are Linux-only)
add_executable(test_nm_device
    tests/network/test_nm_device.cpp
    src/network/nm_device.cpp
    src/network/nm_connection.cpp
    src/logger/logger.cpp
)
target_include_directories(test_nm_device PRIVATE src)
target_link_libraries(test_nm_device PRIVATE GTest::gtest_main)
if(UNIX AND NOT APPLE)
    target_link_libraries(test_nm_device PRIVATE ${SDBUS_LIBRARIES})
    target_include_directories(test_nm_device PRIVATE ${SDBUS_INCLUDE_DIRS})
endif()

# Config unit tests
add_executable(test_config
    tests/test_config.cpp
    src/config/yaml_parser.cpp
    src/config/config_manager.cpp
)
target_include_directories(test_config PRIVATE src)
target_link_libraries(test_config PRIVATE GTest::gtest_main)

# Database unit tests
add_executable(test_db
    tests/test_db.cpp
    src/db/database_manager.cpp
)
target_include_directories(test_db PRIVATE src)
target_link_libraries(test_db PRIVATE GTest::gtest_main SQLite3::SQLite3)

# Proclamation sync unit tests
add_executable(test_proclamation_sync
    tests/test_proclamation_sync.cpp
    src/db/database_manager.cpp
    src/network/proclamation_sync.cpp
    src/network/json.cpp
    src/network/api_client.cpp
)
target_include_directories(test_proclamation_sync PRIVATE src)
target_link_libraries(test_proclamation_sync PRIVATE GTest::gtest_main SQLite3::SQLite3 CURL::libcurl)

# Portal API client unit tests (offline parse tests + live-API tests)
add_executable(test_api_client
    tests/test_api_client.cpp
    src/network/api_client.cpp
    src/network/json.cpp
    src/network/proclamation_sync.cpp
    src/db/database_manager.cpp
)
target_include_directories(test_api_client PRIVATE src)
target_link_libraries(test_api_client PRIVATE GTest::gtest_main CURL::libcurl SQLite3::SQLite3)

# License validation service unit tests (offline + live-API tests)
add_executable(test_license_service
    tests/test_license_service.cpp
    src/network/license_service.cpp
    src/network/api_client.cpp
    src/network/json.cpp
    src/db/database_manager.cpp
)
target_include_directories(test_license_service PRIVATE src)
target_link_libraries(test_license_service PRIVATE GTest::gtest_main CURL::libcurl SQLite3::SQLite3)

# License status tracker unit tests (offline mapping + worker lifecycle)
add_executable(test_license_status
    tests/test_license_status.cpp
    src/network/license_status.cpp
    src/network/license_service.cpp
    src/network/api_client.cpp
    src/network/json.cpp
    src/db/database_manager.cpp
)
target_include_directories(test_license_status PRIVATE src)
target_link_libraries(test_license_status PRIVATE GTest::gtest_main CURL::libcurl SQLite3::SQLite3)

# Validation/format unit tests
add_executable(test_validation
    tests/test_validation.cpp
    src/validation.cpp
)
target_include_directories(test_validation PRIVATE src)
target_link_libraries(test_validation PRIVATE GTest::gtest_main)

# Date/time format unit tests
add_executable(test_date_format
    tests/test_date_format.cpp
    src/date_format.cpp
)
target_include_directories(test_date_format PRIVATE src)
target_link_libraries(test_date_format PRIVATE GTest::gtest_main)

# TimeZone unit tests
add_executable(test_timezone
    tests/test_timezone.cpp
    src/timezone_helper.cpp
)
target_include_directories(test_timezone PRIVATE src)
target_link_libraries(test_timezone PRIVATE GTest::gtest_main)

# Logger unit tests
add_executable(test_logger
    tests/test_logger.cpp
    src/logger/logger.cpp
)
target_include_directories(test_logger PRIVATE src)
target_link_libraries(test_logger PRIVATE GTest::gtest_main)

# Audio unit tests
add_executable(test_audio
    tests/test_audio.cpp
    src/audio/audio_manager.cpp
    src/config/yaml_parser.cpp
    src/config/config_manager.cpp
    src/logger/logger.cpp
)
target_include_directories(test_audio PRIVATE src)
target_link_libraries(test_audio PRIVATE GTest::gtest_main SDL3_mixer::SDL3_mixer SDL3::SDL3)

# Audio downloader unit tests
add_executable(test_audio_downloader
    tests/test_audio_downloader.cpp
    src/audio/audio_downloader.cpp
    src/db/database_manager.cpp
    src/logger/logger.cpp
)
target_include_directories(test_audio_downloader PRIVATE src)
target_link_libraries(test_audio_downloader PRIVATE GTest::gtest_main CURL::libcurl OpenSSL::Crypto SQLite3::SQLite3)

# Scroller Fibonacci pattern unit tests
add_executable(test_fibonacci_pattern
    tests/test_fibonacci_pattern.cpp
    src/fibonacci_line_pattern.cpp
)
target_include_directories(test_fibonacci_pattern PRIVATE src)
target_link_libraries(test_fibonacci_pattern PRIVATE GTest::gtest_main)

# Scroller streams unit tests
add_executable(test_scroller_streams
    tests/test_scroller_streams.cpp
    src/scroller_streams.cpp
)
target_include_directories(test_scroller_streams PRIVATE src)
target_link_libraries(test_scroller_streams PRIVATE GTest::gtest_main SQLite3::SQLite3)

# Fibonacci affine image scrambler unit tests
add_executable(test_fibonacci_scrambler
    tests/test_fibonacci_scrambler.cpp
    src/scramble/fibonacci_scrambler.cpp
)
target_include_directories(test_fibonacci_scrambler PRIVATE src)
target_link_libraries(test_fibonacci_scrambler PRIVATE GTest::gtest_main)

# Color palette API + storage unit tests (readiness: not wired into the app yet)
add_executable(test_color_palettes
    tests/test_color_palettes.cpp
    src/network/api_client.cpp
    src/network/json.cpp
    src/network/proclamation_sync.cpp
    src/db/database_manager.cpp
)
target_include_directories(test_color_palettes PRIVATE src)
target_link_libraries(test_color_palettes PRIVATE GTest::gtest_main CURL::libcurl SQLite3::SQLite3)
