# ========================================================
# ROOT CMakeLists.txt
# Đặt ở: Navigations/CMakeLists.txt
# ========================================================
cmake_minimum_required(VERSION 3.0.2)
project(navigations VERSION 1.0.0 LANGUAGES CXX)

# Chuẩn C++
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Build type
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

# Flags chung
# Warning flags - disabled to suppress warnings during build
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w")  # -w suppresses all warnings
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")

message(STATUS "========================================")
message(STATUS "Building Navigations Project")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS "========================================")

# Build các packages theo thứ tự phụ thuộc
# 1. Core libraries (header-only hoặc base libraries)

if (NOT TARGET robot_time)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/robot_time)
endif()

if (NOT TARGET xmlrpcpp)
   add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/xmlrpcpp) 
endif()

if (NOT TARGET robot_cpp)
   add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/robot_cpp) 
endif()

if (NOT TARGET data_convert)
   add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/data_convert) 
endif()

if (NOT TARGET geometry2)
   add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/geometry2) 
endif()

if (NOT TARGET common_msgs)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/common_msgs) 
endif()

if (NOT TARGET laser_geometry)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/laser_geometry) 
endif()

if (NOT TARGET voxel_grid)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/voxel_grid) 
endif()

if (NOT TARGET robot_nav_2d_msgs)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/robot_nav_2d_msgs) 
endif()

if (NOT TARGET costmap_2d)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/costmap_2d)
endif()

if (NOT TARGET robot_nav_2d_utils)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/robot_nav_2d_utils) 
endif()

if (NOT TARGET laser_filter)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Libraries/laser_filter) 
endif()

if (NOT TARGET robot_nav_core)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Cores/robot_nav_core)
endif()

if (NOT TARGET nav_grid)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Libraries/nav_grid) 
endif()

if (NOT TARGET robot_nav_core2)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Cores/robot_nav_core2)
endif()

if (NOT TARGET robot_nav_core_adapter)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Cores/robot_nav_core_adapter)
endif()

if (NOT TARGET move_base_core)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Cores/move_base_core)
endif()

if (NOT TARGET mkt_msgs)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Libraries/mkt_msgs)
endif()

if (NOT TARGET angles)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Libraries/angles)
endif()

if (NOT TARGET kalman)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Libraries/kalman)
endif()

if (NOT TARGET score_algorithm)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Cores/score_algorithm)
endif()

if (NOT TARGET mkt_plugins)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Libraries/mkt_plugins)
endif()

if (NOT TARGET mkt_algorithm)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Libraries/mkt_algorithm)
endif()

if (NOT TARGET two_points_planner)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Packages/global_planners/two_points_planner)
endif()

if (NOT TARGET custom_planner)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Packages/global_planners/custom_planner)
endif()

if (NOT TARGET dock_planner)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Packages/global_planners/dock_planner)
endif()

if (NOT TARGET pnkx_local_planner)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Algorithms/Packages/local_planners/pnkx_local_planner)
endif()

if (NOT TARGET robot_actionlib_msgs)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Libraries/robot_actionlib_msgs)
endif()

if (NOT TARGET robot_move_base_msgs)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Libraries/robot_move_base_msgs)
endif()

if (NOT TARGET robot_clear_costmap_recovery)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Libraries/robot_clear_costmap_recovery)
endif()

# 3. Packages being migrated from AMR_T800/Test
#
# Prefer the future in-tree location.  Until the migration is physically done,
# keep the current sibling Test directory buildable from this root CMake file.
option(PNKX_NAV_CORE_BUILD_TEST_PACKAGES
       "Build navigation packages currently kept in AMR_T800/Test"
       ON)

option(PNKX_NAV_CORE_BUILD_CATKIN_TEST_PACKAGES
       "Build Test packages that require a catkin workspace instead of standalone CMake"
       OFF)

set(PNKX_NAV_CORE_TEST_PACKAGES_DIR ""
    CACHE PATH "Directory containing the migrated navigation Test packages")

if(NOT PNKX_NAV_CORE_TEST_PACKAGES_DIR)
    if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/Test")
        set(PNKX_NAV_CORE_TEST_PACKAGES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Test")
    elseif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../Test")
        set(PNKX_NAV_CORE_TEST_PACKAGES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../Test")
    endif()
endif()

function(pnkx_add_test_package package_name)
    set(package_dir "${PNKX_NAV_CORE_TEST_PACKAGES_DIR}/${package_name}")
    if(EXISTS "${package_dir}/CMakeLists.txt")
        message(STATUS "[pnkx_nav_core] Adding migrated Test package: ${package_name}")
        add_subdirectory("${package_dir}" "${CMAKE_BINARY_DIR}/Test/${package_name}")
    else()
        message(WARNING
                "[pnkx_nav_core] Test package '${package_name}' was not found in "
                "'${PNKX_NAV_CORE_TEST_PACKAGES_DIR}'.")
    endif()
endfunction()

if(PNKX_NAV_CORE_BUILD_TEST_PACKAGES)
    if(NOT PNKX_NAV_CORE_TEST_PACKAGES_DIR)
        message(FATAL_ERROR
                "PNKX_NAV_CORE_BUILD_TEST_PACKAGES is ON, but no Test package directory was found. "
                "Set PNKX_NAV_CORE_TEST_PACKAGES_DIR explicitly.")
    endif()

    # Foundation and message packages.
    pnkx_add_test_package(angles)
    pnkx_add_test_package(image_geometry)
    pnkx_add_test_package(grid_map_core)
    pnkx_add_test_package(vda5050_msgs)

    # Planner libraries and plugins.  SBPL must precede its lattice plugin.
    pnkx_add_test_package(sbpl)
    pnkx_add_test_package(sbpl_lattice_planner)
    pnkx_add_test_package(base_local_planner)
    pnkx_add_test_package(hybrid_local_planner)
    pnkx_add_test_package(mppi_local_planner)
    pnkx_add_test_package(priest_local_planner)
    pnkx_add_test_package(stanley_local_planner)

    # Supporting runtime packages and test utilities.
    pnkx_add_test_package(depth_image_proc)
    pnkx_add_test_package(action_core)
    pnkx_add_test_package(recovery_core)
    pnkx_add_test_package(mission_adapters)
    pnkx_add_test_package(nav_test_harness)

    # Must be last: it consumes planners, actions, recovery and mission APIs.
    pnkx_add_test_package(move_base2)
endif()

# These packages call find_package(catkin REQUIRED ...) for T800 packages.
# Keep them outside the standalone graph until their dependencies export
# *Config.cmake files, or build them through a catkin workspace.
if(PNKX_NAV_CORE_BUILD_CATKIN_TEST_PACKAGES)
    pnkx_add_test_package(deep_mpc_local_planner)
    pnkx_add_test_package(nav_ros_bridge)
    pnkx_add_test_package(depth_local_costmap_noetic_test)
endif()

# 2. Main packages (phụ thuộc vào cores)
# message(STATUS "[move_base] Shared library configured")
if (NOT TARGET move_base)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/Navigations/Packages/move_base)
endif()

# C API for .NET/C# integration
if (NOT TARGET navigation_c_api)
    add_subdirectory(${CMAKE_SOURCE_DIR}/src/APIs/c_api)
endif()

message(STATUS "========================================")
message(STATUS "All packages configured successfully")
message(STATUS "========================================")
