function(comm_link TARGET_NAME)
    if(COMM_LINK_ATOMIC)
        target_link_libraries(${TARGET_NAME} PUBLIC atomic)
    endif()

    if(COMM_LINK_PTHREAD)
        target_link_libraries(${TARGET_NAME} PUBLIC pthread)
    endif()

    target_link_libraries(${TARGET_NAME} PUBLIC TracyClient)
    # if(COMM_LINK_MICROPROFILE)
    #     target_link_libraries(${TARGET_NAME} PUBLIC microprofile)
    # endif()
endfunction()

# cc_library(name STATIC SRCS a.c b.c DEPS PUBLIC pub_lib PRIVATE pri_lib)
function(cc_library TARGET_NAME)
    set(options
        STATIC
        static
        SHARED
        shared
        INTERFACE
        interface)
    set(oneValueArgs "")
    set(multiValueArgs
        SRCS
        DEPS
        INCS)
    # 解析参数三种参数 前缀为cc_library_XXX
    cmake_parse_arguments(
        cc_library
        "${options}"
        "${oneValueArgs}"
        "${multiValueArgs}"
        ${ARGN})
    if(WIN32)
        # add prefix `lib`, suffix `.lib` -> libxxx.lib in windows
        set(${TARGET_NAME}_LIB_NAME
            "${CMAKE_STATIC_LIBRARY_PREFIX}${TARGET_NAME}${CMAKE_STATIC_LIBRARY_PREFIX}"
            CACHE STRING "output library name for target ${TARGET_NAME}")
    endif()

    if(cc_library_SRCS)
        if(cc_library_SHARED OR cc_library_shared)
            add_library(${TARGET_NAME} SHARED ${cc_library_SRCS})
        elseif(cc_library_INTERFACE OR cc_library_interface)
            # add_library(${TARGET_NAME} SHARED ${cc_library_SRCS})
        else()
            add_library(${TARGET_NAME} STATIC ${cc_library_SRCS})
        endif()

        if(cc_library_INCS)
            target_include_directories(${TARGET_NAME} ${cc_library_DEPS})
        endif()

        if(cc_library_DEPS)
            target_link_libraries(${TARGET_NAME} ${cc_library_DEPS})
        endif()
        comm_link(${TARGET_NAME})

    endif()
endfunction()

# cc_library(mylib
#   STATIC
#   SRCS a.c b.c
#   DEPS PUBLIC pub_lib
#        PRIVATE pri_lib
# )
function(cc_executable TARGET_NAME)
    set(oneValueArgs "")
    set(multiValueArgs
        SRCS
        DEPS
        INCS)
    cmake_parse_arguments(
        cc_executable
        "${options}"
        "${oneValueArgs}"
        "${multiValueArgs}"
        ${ARGN})

    if(cc_executable_SRCS)
        list(
            LENGTH
            cc_executable_SRCS
            len_src)
        if("${len_src}"
           GREATER_EQUAL
           1)
            add_executable(${TARGET_NAME} ${cc_executable_SRCS})
        else()
            add_executable(${TARGET_NAME} "")
        endif()
    endif()

    if(cc_executable_INCS)
        target_include_directories(${TARGET_NAME} ${cc_executable_INCS})
    endif()

    if(cc_executable_DEPS)
        target_link_libraries(${TARGET_NAME} ${cc_executable_DEPS})
    endif()

    comm_link(${TARGET_NAME})
endfunction()

function(cc_test TARGET_NAME)
    CPMAddPackage(
        NAME gtest
        URI https://github.com/google/googletest/archive/refs/tags/release-1.12.0.zip
        SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest
        OPTIONS "INSTALL_GTEST OFF"
        FORCE)

    set(options NO_MAIN)
    set(oneValueArgs "")
    set(multiValueArgs
        SRCS
        DEPS
        INCS
        ARGS)
    cmake_parse_arguments(
        cc_test
        "${options}"
        "${oneValueArgs}"
        "${multiValueArgs}"
        ${ARGN})
    # message("TARGET ${TARGET_NAME}")
    cc_executable(
        ${TARGET_NAME}
        SRCS ${cc_test_SRCS}
        DEPS ${cc_test_DEPS}
        INCS ${cc_test_INCS})
    target_link_libraries(${TARGET_NAME} ${cc_test_DEPS} PRIVATE GTest::gtest)
    if(NOT cc_test_NO_MAIN)
        target_link_libraries(${TARGET_NAME} PRIVATE GTest::gtest_main)
    endif()
    add_test(NAME ${TARGET_NAME} COMMAND ${TARGET_NAME})
endfunction()

function(cc_benchmark TARGET_NAME)
    CPMAddPackage(
        NAME benchmark
        URI https://github.com/google/benchmark/archive/refs/tags/v1.8.4.tar.gz
        SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/benchmark
        OPTIONS "BENCHMARK_ENABLE_INSTALL OFF"
                "BENCHMARK_ENABLE_GTEST_TESTS OFF"
        FORCE)

    set(options NO_MAIN)
    set(oneValueArgs "")
    set(multiValueArgs
        SRCS
        DEPS
        INCS
        ARGS)
    cmake_parse_arguments(
        cc_benchmark
        "${options}"
        "${oneValueArgs}"
        "${multiValueArgs}"
        ${ARGN})
    # message("TARGET ${TARGET_NAME}")
    cc_executable(
        ${TARGET_NAME}
        SRCS ${cc_benchmark_SRCS}
        DEPS ${cc_benchmark_DEPS}
        INCS ${cc_benchmark_INCS})
    target_link_libraries(${TARGET_NAME} ${cc_benchmark_DEPS}
                          PRIVATE benchmark::benchmark)
    if(NOT cc_benchmark_NO_MAIN)
        target_link_libraries(${TARGET_NAME} PRIVATE benchmark::benchmark_main)

    endif()
endfunction()
