cmake_minimum_required(VERSION 3.13)
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.12)
    cmake_policy(SET CMP0074 NEW)
endif()

set(ROTOR_LIGHT_VERSION "0.01")
project (rotor_light LANGUAGES CXX VERSION ${ROTOR_LIGHT_VERSION})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")

if (NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET AND
    NOT DEFINED CMAKE_VISIBILITY_INLINES_HIDDEN)
  set(CMAKE_CXX_VISIBILITY_PRESET hidden)
  set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
endif ()

set(ROTOR_LIGHT_DOC OFF CACHE BOOL "generate docs using doxygen")
set(ROTOR_LIGHT_ACTOR "uint64_t" CACHE STRING "ActorId type [default: uint64_t]")
set(ROTOR_LIGHT_TIMEPOINT "int64_t" CACHE STRING "TimePoint type [default: int64_t]")
set(ROTOR_LIGHT_DURATION "std::int_fast32_t" CACHE STRING "Duration type [default: std::int_fast32_t]")
set(ROTOR_LIGHT_MESSAGE "std::uint_fast16_t" CACHE STRING "Message id type [default: std::uint_fast16_t]")
set(ROTOR_LIGHT_EVENT "std::uint16_t" CACHE STRING "Event id type [default: std::uint16_t]")
set(ROTOR_LIGHT_INDEX "std::uint_fast8_t" CACHE STRING "Queue indexing type [default: std::uint_fast8_t]")
set(ROTOR_LIGHT_FW_QUEUE "0" CACHE STRING "Default queue/priority for rotor light framework messages [default: 0]")

include(CMakePrintHelpers)
include(GenerateExportHeader)


if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AVR")
    set(ROTOR_LIGHT_BSP_DIR "avr")
elseif ("${TOOLCHAIN_PREFIX}" MATCHES "^arm-.*")
    set(ROTOR_LIGHT_BSP_DIR "arm")
elseif ("${TOOLCHAIN_PREFIX}" STREQUAL "mb-")
    set(ROTOR_LIGHT_BSP_DIR "mb")
elseif ("${TOOLCHAIN_PREFIX}" STREQUAL "")
    set(ROTOR_LIGHT_BSP_DIR "host")
endif()


set(ROTOR_LIGHT_BSP_PATH "include/rotor-light/bsp/${ROTOR_LIGHT_BSP_DIR}")
add_library(rotor_light_bsp INTERFACE)
target_include_directories(rotor_light_bsp INTERFACE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/${ROTOR_LIGHT_BSP_PATH}>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/${ROTOR_LIGHT_BSP_PATH}>
    $<INSTALL_INTERFACE:include/${ROTOR_LIGHT_BSP_PATH}>
)

add_library(rotor_light
    src/rotor-light/actor.cpp
    src/rotor-light/misc.cpp
    src/rotor-light/queue.cpp
    src/rotor-light/planner.cpp
    src/rotor-light/supervisor.cpp
)

target_include_directories(rotor_light PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

target_compile_features(rotor_light PUBLIC cxx_std_17)
set_target_properties(rotor_light PROPERTIES
    CXX_STANDARD 17
    CXX_STANDARD_REQUIRED YES
    CXX_EXTENSIONS NO
)
target_compile_definitions(rotor_light PUBLIC
    "ROTOR_LIGHT_ACTOR=${ROTOR_LIGHT_ACTOR}"
    "ROTOR_LIGHT_TIMEPOINT=${ROTOR_LIGHT_TIMEPOINT}"
    "ROTOR_LIGHT_DURATION=${ROTOR_LIGHT_DURATION}"
    "ROTOR_LIGHT_MESSAGE=${ROTOR_LIGHT_MESSAGE}"
    "ROTOR_LIGHT_EVENT=${ROTOR_LIGHT_EVENT}"
    "ROTOR_LIGHT_INDEX=${ROTOR_LIGHT_INDEX}"
    "ROTOR_LIGHT_FW_QUEUE=${ROTOR_LIGHT_FW_QUEUE}"
)
target_link_libraries(rotor_light rotor_light_bsp)

if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
    add_subdirectory("examples")

    if ("${TOOLCHAIN_PREFIX}" STREQUAL "")
        include(CTest)
        if (BUILD_TESTING)
            add_subdirectory("tests")
        endif()
    endif()

    find_package(Doxygen)
    if (DOXYGEN_FOUND AND ${ROTOR_LIGHT_DOC})
        set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in)
        set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
        configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
        add_custom_target( doc_doxygen ALL
            COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
            COMMENT "Generating API documentation with Doxygen"
            VERBATIM)
        file(GLOB DOC_IMAGES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/docs/*.png)
        file(COPY ${DOC_IMAGES} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/doxygen)
        message("Doxygen need to be installed to generate the doxygen documentation")
    endif()
endif()
