cmake_minimum_required(VERSION 3.20)
project(fire_gimbal_control LANGUAGES C CXX)

# ---------------------------------------------------------------------------
# Options (runtime toggles still select mock vs real at launch; these control
# whether the heavy/proprietary dependencies are compiled in at all).
# ---------------------------------------------------------------------------
option(WITH_VIMBA "Build with Allied Vision Vimba X camera support" ON)
option(WITH_MQTT  "Build with Eclipse Paho MQTT support"            ON)
option(WITH_TUI   "Build the terminal UI dashboard (FTXUI)"         ON)
option(BUILD_TESTING "Build unit tests" OFF)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()

# ---------------------------------------------------------------------------
# Always-required dependencies
# ---------------------------------------------------------------------------
find_package(Threads REQUIRED)
find_package(OpenCV REQUIRED COMPONENTS core highgui imgproc)
# Boost.Asio is header-only (Boost >= 1.69); only program_options is a compiled lib.
if(POLICY CMP0167)
  cmake_policy(SET CMP0167 NEW)
endif()
find_package(Boost REQUIRED CONFIG COMPONENTS program_options)

# libjxl via pkg-config (Arch/Manjaro ship a .pc file)
find_package(PkgConfig REQUIRED)
pkg_check_modules(JXL REQUIRED IMPORTED_TARGET libjxl libjxl_threads)

# ---------------------------------------------------------------------------
# fgc_core: SDK-independent core (config, path resolution, and - as the
# refactor proceeds - logging, the capture scheduler and the I/O interfaces).
# Builds and unit-tests WITHOUT Vimba X or Paho, so the core logic is
# verifiable on any machine.
# ---------------------------------------------------------------------------
add_library(fgc_core STATIC
  src/core/Config.cpp
  src/core/Paths.cpp
  src/core/Logger.cpp
  src/core/Geometry.cpp
  src/core/ScanGrid.cpp
  src/core/TelemetryParser.cpp
  src/core/CaptureScheduler.cpp
  src/core/CommandParser.cpp
  src/core/HelpText.cpp
  src/core/DumpParser.cpp
  src/core/DiagParser.cpp
  src/core/Calibration.cpp
  src/core/CalibrationRoutine.cpp
  src/core/MtiProtocol.cpp
  src/ui/UiSnapshot.cpp
  src/ui/HeadlessUi.cpp
  ini.c
)
target_include_directories(fgc_core PUBLIC
  ${CMAKE_SOURCE_DIR}/include
  ${CMAKE_SOURCE_DIR}        # for the bundled ini.h
)
target_link_libraries(fgc_core PUBLIC Threads::Threads)

# ---------------------------------------------------------------------------
# Application executable. Camera image pipeline + serial controller always
# build (OpenCV/libjxl/Boost.Asio are available everywhere); MQTT and Vimba
# sources are added only when their option is ON.
# ---------------------------------------------------------------------------
set(FGC_SOURCES
  main.cpp
  src/core/Application.cpp
  src/camera/JpegXlEncoder.cpp
  src/camera/ImagePipeline.cpp
  src/serial/SerialMotorController.cpp
  src/serial/MtiImuSource.cpp
)
if(WITH_MQTT)
  list(APPEND FGC_SOURCES src/mqtt/MqttControlChannel.cpp)
endif()
if(WITH_VIMBA)
  list(APPEND FGC_SOURCES src/camera/VimbaCameraSource.cpp)
endif()

add_executable(fire_gimbal_control ${FGC_SOURCES})
target_include_directories(fire_gimbal_control PRIVATE ${CMAKE_SOURCE_DIR})

target_link_libraries(fire_gimbal_control PRIVATE
  fgc_core
  ${OpenCV_LIBS}
  Boost::headers
  Boost::program_options
  PkgConfig::JXL
)

# ---------------------------------------------------------------------------
# Optional: MQTT (Eclipse Paho). Fetched + built from pinned, hash-verified
# upstream release tarballs (no AUR, no system install required).
# ---------------------------------------------------------------------------
if(WITH_MQTT)
  include(cmake/Paho.cmake)
  target_link_libraries(fire_gimbal_control PRIVATE PahoMqttCpp::paho-mqttpp3-static)
  target_compile_definitions(fire_gimbal_control PRIVATE FGC_WITH_MQTT=1)
else()
  target_compile_definitions(fire_gimbal_control PRIVATE FGC_WITH_MQTT=0)
  message(STATUS "WITH_MQTT=OFF: building without MQTT support")
endif()

# ---------------------------------------------------------------------------
# Optional: Vimba X SDK (proprietary; install manually from Allied Vision).
# ---------------------------------------------------------------------------
if(WITH_VIMBA)
  find_package(Vmb REQUIRED)
  target_link_libraries(fire_gimbal_control PRIVATE Vmb::VmbC Vmb::VmbCPP)
  target_compile_definitions(fire_gimbal_control PRIVATE FGC_WITH_VIMBA=1)
else()
  target_compile_definitions(fire_gimbal_control PRIVATE FGC_WITH_VIMBA=0)
  message(STATUS "WITH_VIMBA=OFF: building without Vimba X camera support (mock cameras only)")
endif()

# ---------------------------------------------------------------------------
# Optional: terminal UI (FTXUI). The TuiUi source and the FTXUI link are added
# only when ON; the SDK-independent core (HeadlessUi, UiSnapshot) is unaffected,
# so a headless build needs no extra dependency.
# ---------------------------------------------------------------------------
if(WITH_TUI)
  include(cmake/Ftxui.cmake)
  target_sources(fire_gimbal_control PRIVATE src/ui/TuiUi.cpp)
  target_link_libraries(fire_gimbal_control PRIVATE ftxui::component ftxui::dom ftxui::screen)
  target_compile_definitions(fire_gimbal_control PRIVATE FGC_WITH_TUI=1)
else()
  target_compile_definitions(fire_gimbal_control PRIVATE FGC_WITH_TUI=0)
  message(STATUS "WITH_TUI=OFF: building without the terminal dashboard (headless console only)")
endif()

# ---------------------------------------------------------------------------
# Tests
# ---------------------------------------------------------------------------
if(BUILD_TESTING)
  enable_testing()
  add_subdirectory(tests)
endif()

# ---------------------------------------------------------------------------
# Summary
# ---------------------------------------------------------------------------
message(STATUS "------------------------------------------------------------")
message(STATUS "fire_gimbal_control configuration")
message(STATUS "  build type : ${CMAKE_BUILD_TYPE}")
message(STATUS "  WITH_VIMBA : ${WITH_VIMBA}")
message(STATUS "  WITH_MQTT  : ${WITH_MQTT}")
message(STATUS "  WITH_TUI   : ${WITH_TUI}")
message(STATUS "  tests      : ${BUILD_TESTING}")
message(STATUS "------------------------------------------------------------")
