cmake_minimum_required(VERSION 3.14)
project(LHandProLib_CAN_Test LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# SDK root: ${SDK_INSTALL_SHARE_DIR}/examples/CAN_cpp/cmake -> ../../../../
set(SDK_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
message(STATUS "SDK Root Directory: ${SDK_ROOT_DIR}")

if(NOT DEFINED SDK_DIST_NAME)
    file(GLOB SDK_INCLUDE_CANDIDATES LIST_DIRECTORIES true "${SDK_ROOT_DIR}/include/*")
    list(LENGTH SDK_INCLUDE_CANDIDATES SDK_INCLUDE_COUNT)
    if(SDK_INCLUDE_COUNT EQUAL 1)
        list(GET SDK_INCLUDE_CANDIDATES 0 SDK_INCLUDE_DIR)
        get_filename_component(SDK_DIST_NAME "${SDK_INCLUDE_DIR}" NAME)
    else()
        set(SDK_DIST_NAME "LHandProLib")
    endif()
endif()
set(SDK_LIBRARY_NAME "${SDK_DIST_NAME}" CACHE STRING "SDK library base name")
set(SDK_INCLUDE_SUBDIR "${SDK_DIST_NAME}" CACHE STRING "SDK include subdirectory")
set(SDK_DLL_NAME "${SDK_LIBRARY_NAME}.dll")
set(SDK_CPP_HEADER_NAME "${SDK_DIST_NAME}.hpp" CACHE STRING "SDK C++ header file name")
set(SDK_C_HEADER_NAME "${SDK_DIST_NAME}.h" CACHE STRING "SDK C header file name")
set(SDK_EXAMPLE_NAME "${SDK_DIST_NAME}_CAN_Test" CACHE STRING "CAN example executable name")
add_compile_definitions(
    SDK_CPP_HEADER="${SDK_CPP_HEADER_NAME}"
    SDK_C_HEADER="${SDK_C_HEADER_NAME}"
)
# Output paths
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)

foreach(cfg DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${cfg} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${cfg} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${cfg} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endforeach()

# Source files are one level up (installed alongside this cmake/ dir)
set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..)

add_executable(LHandProLib_CAN_Test
    ${SRC_DIR}/main.cpp
    ${SRC_DIR}/PCANBus.cpp
)
set_target_properties(LHandProLib_CAN_Test PROPERTIES
    OUTPUT_NAME "${SDK_EXAMPLE_NAME}"
)

# LHandProLib
find_library(SDK_LIB NAMES ${SDK_LIBRARY_NAME} LHandProLib PATHS ${SDK_ROOT_DIR}/lib REQUIRED)

# PCAN
if(WIN32)
    if(CMAKE_SIZEOF_VOID_P EQUAL 4)
        message(STATUS "Building for 32-bit (x86)")
        set(PCAN_LIB_PATH ${SRC_DIR}/x86/lib/PCANBasic.lib)
        set(PCAN_DLL_PATH ${SRC_DIR}/x86/PCANBasic.dll)
    elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
        message(STATUS "Building for 64-bit (x64)")
        set(PCAN_LIB_PATH ${SRC_DIR}/x64/lib/PCANBasic.lib)
        set(PCAN_DLL_PATH ${SRC_DIR}/x64/PCANBasic.dll)
    else()
        message(FATAL_ERROR "Unknown architecture: ${CMAKE_SIZEOF_VOID_P}")
    endif()

    target_link_libraries(LHandProLib_CAN_Test PRIVATE
        ${SDK_LIB}
        ${PCAN_LIB_PATH}
    )
else()
    target_link_libraries(LHandProLib_CAN_Test PRIVATE
        ${SDK_LIB}
        pcanbasic
    )
endif()

# Include directories
target_include_directories(LHandProLib_CAN_Test PRIVATE
    ${SDK_ROOT_DIR}/include/${SDK_INCLUDE_SUBDIR}
    ${SRC_DIR}
    ${SRC_DIR}/include
)

# Windows: copy DLL to output after build
if(WIN32)
    add_custom_command(TARGET LHandProLib_CAN_Test POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
            "${PCAN_DLL_PATH}"
            "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/PCANBasic.dll"
    )
endif()

# Install
install(TARGETS LHandProLib_CAN_Test RUNTIME DESTINATION bin)

if(WIN32)
    install(FILES ${PCAN_DLL_PATH} DESTINATION bin)
endif()

# Linux: copy LHandProLib shared library alongside the binary
if(UNIX AND NOT APPLE)
    install(DIRECTORY ${SDK_ROOT_DIR}/lib/ DESTINATION bin)
endif()
