cmake_minimum_required(VERSION 3.5)
project(web_video_server)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

find_package(ament_cmake_ros REQUIRED)

find_package(async_web_server_cpp REQUIRED)
find_package(cv_bridge REQUIRED)
find_package(image_transport REQUIRED)
find_package(pluginlib REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)
find_package(rmw REQUIRED)
find_package(sensor_msgs REQUIRED)

find_package(OpenCV REQUIRED)
find_package(Boost REQUIRED COMPONENTS system)

find_package(PkgConfig REQUIRED)
pkg_check_modules(avcodec libavcodec REQUIRED)
pkg_check_modules(avformat libavformat REQUIRED)
pkg_check_modules(avutil libavutil REQUIRED)
pkg_check_modules(swscale libswscale REQUIRED)

if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()

###################################################
## Declare things to be passed to other projects ##
###################################################

###########
## Build ##
###########

if(${cv_bridge_VERSION} VERSION_LESS "3.3.0")
  add_compile_definitions(CV_BRIDGE_USES_OLD_HEADERS)
endif()

## Declare a cpp library
add_library(${PROJECT_NAME} SHARED
  src/web_video_server.cpp
  src/multipart_stream.cpp
  src/streamer.cpp
  src/utils.cpp
)

target_include_directories(${PROJECT_NAME}
  PUBLIC
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
    "$<INSTALL_INTERFACE:include/${PROJECT_NAME}>"
)

## Specify libraries to link a library or executable target against
target_link_libraries(${PROJECT_NAME}
  PUBLIC
    async_web_server_cpp::async_web_server_cpp
    pluginlib::pluginlib
    rclcpp::rclcpp
    rmw::rmw
    Boost::boost
  PRIVATE
    rclcpp_components::component
)

add_library(${PROJECT_NAME}_streamers SHARED
  src/streamers/image_transport_streamer.cpp
  src/streamers/libav_streamer.cpp
  src/streamers/h264_streamer.cpp
  src/streamers/jpeg_streamers.cpp
  src/streamers/png_streamers.cpp
  src/streamers/ros_compressed_streamer.cpp
  src/streamers/vp8_streamer.cpp
  src/streamers/vp9_streamer.cpp
)

target_include_directories(${PROJECT_NAME}_streamers
  PUBLIC
    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
    "$<INSTALL_INTERFACE:include/${PROJECT_NAME}>"
    ${avcodec_INCLUDE_DIRS}
    ${avformat_INCLUDE_DIRS}
    ${avutil_INCLUDE_DIRS}
    ${swscale_INCLUDE_DIRS}
)

target_link_libraries(${PROJECT_NAME}_streamers
  ${PROJECT_NAME}
  async_web_server_cpp::async_web_server_cpp
  cv_bridge::cv_bridge
  image_transport::image_transport
  pluginlib::pluginlib
  rclcpp::rclcpp
  ${sensor_msgs_TARGETS}
  Boost::boost
  Boost::system
  ${OpenCV_LIBS}
  ${avcodec_LIBRARIES}
  ${avformat_LIBRARIES}
  ${avutil_LIBRARIES}
  ${swscale_LIBRARIES}
)

## Declare a cpp executable
add_executable(${PROJECT_NAME}_node
  src/web_video_server_node.cpp
)

target_link_libraries(${PROJECT_NAME}_node
  ${PROJECT_NAME}
)

rclcpp_components_register_nodes(${PROJECT_NAME} "web_video_server::WebVideoServer")

pluginlib_export_plugin_description_file(web_video_server plugins.xml)

#############
## Install ##
#############

install(
  DIRECTORY include/
  DESTINATION include/${PROJECT_NAME}
)

install(
  TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_streamers
  EXPORT export_${PROJECT_NAME}
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
)
ament_export_targets(export_${PROJECT_NAME} HAS_LIBRARY_TARGET)
ament_export_dependencies(
  async_web_server_cpp
  cv_bridge
  image_transport
  pluginlib
  rclcpp
  rmw
  sensor_msgs
)

set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
install(
  TARGETS ${PROJECT_NAME}_node
  DESTINATION lib/${PROJECT_NAME}
)

###########
## Tests ##
###########

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)

  # Skip ament_copyright check for humble
  if($ENV{ROS_DISTRO} STREQUAL "humble")
    list(APPEND AMENT_LINT_AUTO_EXCLUDE
      ament_cmake_copyright
    )
  endif()

  option(ENABLE_CLANG_TIDY "Enable ament_clang_tidy test" OFF)
  if(ENABLE_CLANG_TIDY)
    include(ProcessorCount)
    processorcount(N)
    set(ament_cmake_clang_tidy_JOBS ${N})
  else()
    list(APPEND AMENT_LINT_AUTO_EXCLUDE
      ament_cmake_clang_tidy
    )
  endif()

  ament_lint_auto_find_test_dependencies()
endif()

ament_package(
  CONFIG_EXTRAS "config-extras.cmake"
)
