cmake_minimum_required(VERSION 3.10)

# ========================================================
# Dual-mode CMakeLists.txt: Supports both Catkin and Standalone CMake
# ========================================================

# Detect if building with Catkin
if(DEFINED CATKIN_DEVEL_PREFIX OR DEFINED CATKIN_TOPLEVEL)
  set(BUILDING_WITH_CATKIN TRUE)
  message(STATUS "Building move_base with Catkin")
else()
  set(BUILDING_WITH_CATKIN FALSE)
  message(STATUS "Building move_base with Standalone CMake")
endif()

# Tên dự án
project(move_base VERSION 1.0.0 LANGUAGES CXX)

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

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

# ========================================================
# Find Packages
# ========================================================
find_package(Boost REQUIRED)


# ========================================================
# Source Files
# ========================================================
file(GLOB SOURCES "src/move_base.cpp")
file(GLOB HEADERS "include/move_base/move_base.h")

# ========================================================
# Include Directories
# ========================================================
include_directories(
  ${PROJECT_SOURCE_DIR}/include
)


# ========================================================
# RPATH settings: ưu tiên thư viện build tại chỗ
# ========================================================
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_BUILD_RPATH "${CMAKE_BINARY_DIR}/src/Libraries/robot_costmap_2d:${CMAKE_BINARY_DIR}/src/Libraries/node_handle:${CMAKE_BINARY_DIR}/src/Libraries/tf3:${CMAKE_BINARY_DIR}/src/Libraries/robot_time:${CMAKE_BINARY_DIR}/src/Libraries/xmlrpcpp")
set(CMAKE_INSTALL_RPATH "${CMAKE_BINARY_DIR}/src/Libraries/robot_costmap_2d:${CMAKE_BINARY_DIR}/src/Libraries/node_handle:${CMAKE_BINARY_DIR}/src/Libraries/tf3:${CMAKE_BINARY_DIR}/src/Libraries/robot_time:${CMAKE_BINARY_DIR}/src/Libraries/xmlrpcpp")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# ========================================================
# Create Library
# ========================================================
add_library(move_base SHARED ${SOURCES} ${HEADERS})

# ========================================================
# Dependencies and Link Libraries
# ========================================================

# Standalone CMake mode: link all dependencies manually
set(PACKAGES_DIR 
  geometry_msgs 
  robot_std_msgs 
  move_base_core 
  nav_core 
  robot_costmap_2d 
  plugins  # Link với plugins library để có StaticLayer typeinfo
  yaml-cpp
  robot_tf3_sensor_msgs
  robot_tf3_geometry_msgs
  data_convert
  dl
  pthread
  robot_nav_2d_utils
)

target_link_libraries(move_base 
  PUBLIC ${PACKAGES_DIR} 
  PUBLIC robot_cpp
  PRIVATE Boost::boost
)

# Set RPATH để ưu tiên thư viện build cục bộ
set_target_properties(move_base PROPERTIES
  LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
)


# ========================================================
# Include Directories for Target
# ========================================================
target_include_directories(move_base
  PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

if(BUILDING_WITH_CATKIN)
  target_include_directories(move_base
    PUBLIC ${catkin_INCLUDE_DIRS}
  )
endif()

# ========================================================
# Executable
# ========================================================
add_executable(move_base_main src/move_base_main.cpp)
target_link_libraries(move_base_main 
  PRIVATE move_base robot_cpp
  PRIVATE Boost::boost
)

# Set RPATH for executable to find libraries in build directory first
# Use RPATH instead of RUNPATH for higher priority

# Force use of RPATH instead of RUNPATH
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--disable-new-dtags")

# ========================================================
# Installation
# ========================================================

# Standalone CMake installation
install(DIRECTORY include/move_base 
  DESTINATION include
  FILES_MATCHING PATTERN "*.h"
)

install(TARGETS move_base move_base_main
  EXPORT move_base-targets
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
)

install(EXPORT move_base-targets
  FILE move_base-targets.cmake
  DESTINATION lib/cmake/move_base
)


# ========================================================
# Build Options
# ========================================================
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(BUILD_TESTS "Build test programs" OFF)

# ========================================================
# Compiler Flags
# ========================================================
# 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")

# ========================================================
# Status Messages
# ========================================================
message(STATUS "=================================")
message(STATUS "Project: ${PROJECT_NAME}")
message(STATUS "Version: ${PROJECT_VERSION}")
message(STATUS "Build mode: ${BUILDING_WITH_CATKIN}")
message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Headers found:")
foreach(hdr ${HEADERS})
    message(STATUS "  - ${hdr}")
endforeach()
message(STATUS "=================================")
