cmake_minimum_required(VERSION 3.20)

set(_MCP2221A_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "MCP2221A library directory")

# Function to copy the MCP2221 DLL to the target directory after build
function(copy_runtime_dll target)
    if(WIN32)

        set(_dll_path "${_MCP2221A_CMAKE_DIR}/MCP2221_DLL/unmanaged/dll/mcp2221_dll_um_x64.dll")
        # Make sure backslashes are converted to forward slashes for Windows
        file(TO_CMAKE_PATH "${_dll_path}" _dll_path_normalized)
        
        add_custom_command(TARGET ${target} POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different
                "${_dll_path_normalized}"
                $<TARGET_FILE_DIR:${target}>
            COMMENT "Copying MCP2221 DLL to output directory"
        )
    endif()
endfunction()

option(BUILD_TESTS "Build the tests" ON)

project(mcp2221a LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD_REQUIRED 20)

if (UNIX)
    include(ExternalProject)
    set(EXTERNAL_DIR ${CMAKE_CURRENT_BINARY_DIR}/external)

    # Download and build i2c-tools
    ExternalProject_Add(
        i2c-tools
        GIT_REPOSITORY https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git
        GIT_TAG v4.4
        PREFIX ${EXTERNAL_DIR}/i2c-tools
        SOURCE_DIR ${EXTERNAL_DIR}/i2c-tools/src
        STAMP_DIR ${EXTERNAL_DIR}/i2c-tools/stamp
        CONFIGURE_COMMAND ""
        BUILD_COMMAND make BUILD_STATIC_LIB=1 -j4
        BUILD_IN_SOURCE 1
        INSTALL_COMMAND ""
    )

    # Get build directory of i2c-tools
    ExternalProject_Get_Property(i2c-tools BINARY_DIR)
    message(STATUS "i2c-tools build directory: ${BINARY_DIR}")
    set(I2C_LIB_PATH ${BINARY_DIR}/lib/libi2c.a)
    set(I2C_INCLUDE_DIR ${EXTERNAL_DIR}/i2c-tools/src/include)

    add_library(i2c STATIC IMPORTED)
    set_target_properties(i2c PROPERTIES IMPORTED_LOCATION ${I2C_LIB_PATH})
    include_directories(${I2C_INCLUDE_DIR})
    
    # Prepare configure script for libusb
    file(WRITE ${EXTERNAL_DIR}/libusb/build/configure_libusb.sh
        "#!/bin/bash
        set -e

        STAMP_FILE=\"${EXTERNAL_DIR}/libusb/stamp/libusb-configured\"
        BUILD_DIR=\"${EXTERNAL_DIR}/libusb/build\"
        SRC_DIR=\"${EXTERNAL_DIR}/libusb/src\"
        INSTALL_DIR=\"${EXTERNAL_DIR}/libusb/install\"

        if [ ! -f \"$STAMP_FILE\" ]; then
            echo \"Running bootstrap and configure...\"
            cd \"$BUILD_DIR\"
            \"$SRC_DIR\"/bootstrap.sh
            \"$SRC_DIR\"/configure --disable-udev --enable-static --disable-shared --prefix=\"$INSTALL_DIR\"
            touch \"$STAMP_FILE\"
        else
            echo \"Skipping configure: stamp exists\"
        fi
    ")
    file(CHMOD ${EXTERNAL_DIR}/libusb/build/configure_libusb.sh PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ)

    # Download and build libusb
    ExternalProject_Add(
        libusb
        GIT_REPOSITORY https://github.com/libusb/libusb.git
        GIT_TAG v1.0.27

        PREFIX ${EXTERNAL_DIR}/libusb
        SOURCE_DIR ${EXTERNAL_DIR}/libusb/src
        STAMP_DIR ${EXTERNAL_DIR}/libusb/stamp
        BINARY_DIR ${EXTERNAL_DIR}/libusb/build
        INSTALL_DIR ${EXTERNAL_DIR}/libusb/install

        CONFIGURE_COMMAND
            bash ${EXTERNAL_DIR}/libusb/build/configure_libusb.sh            
        BUILD_COMMAND make -j4
        # BUILD_IN_SOURCE 1
        INSTALL_COMMAND ""
    )
    ExternalProject_Get_Property(libusb BINARY_DIR)
    message(STATUS "libusb build directory: ${BINARY_DIR}")
    set(LIBUSB_LIB_PATH ${BINARY_DIR}/libusb/.libs/libusb-1.0.a)
    set(LIBUSB_INCLUDE_DIR ${EXTERNAL_DIR}/libusb/src/libusb)

    add_library(libusb-1.0.27 STATIC IMPORTED)
    set_target_properties(libusb PROPERTIES IMPORTED_LOCATION ${LIBUSB_LIB_PATH})
    include_directories(${LIBUSB_INCLUDE_DIR})
    message(STATUS "Libusb include dir: ${LIBUSB_INCLUDE_DIR}, lib path: ${LIBUSB_LIB_PATH}")

elseif(WIN32)
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/MCP2221_DLL/unmanaged/dll)
    set(MCP_DLL "${CMAKE_CURRENT_SOURCE_DIR}/MCP2221_DLL/unmanaged/dll/mcp2221_dll_um_x64.dll" CACHE INTERNAL "Path to MCP2221 DLL")
endif()

include_directories(
    lib
)
add_subdirectory(lib)

if (BUILD_TESTS)
    add_subdirectory(tests)
endif()