macro(import_grpc)
    find_package(Threads REQUIRED)
    if(IMPORT_GRPC_BY_SUBMODULE)
        import_grpc_by_submodule(${GRPC_SUBMODULE_DIR})
    elseif(IMPORT_GRPC_BY_FETCHCONTENT)
        import_grpc_by_fetchcontent(${GRPC_FETCHCONTENT_VERSION})
    else()
        import_grpc_by_preinstalled()
    endif()
endmacro()

# usage: import_grpc_by_submodule("${CMAKE_SOURCE_DIR}/lib/grpc")
macro(import_grpc_by_submodule grpc_dir)
    message(STATUS "Using gRPC via SubModule with dir: ${grpc_dir}")
    add_subdirectory(${grpc_dir})

    set(_PROTOBUF_LIBPROTOBUF libprotobuf)
    set(_REFLECTION grpc++_reflection)
    if(CMAKE_CROSSCOMPILING)
        find_program(_PROTOBUF_PROTOC protoc)
    else()
        set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
    endif()
    set(_GRPC_GRPCPP grpc++)
    if(CMAKE_CROSSCOMPILING)
        find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
    else()
        set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
    endif()
endmacro()

# usage: import_grpc_by_fetchcontent(1.32.0)
macro(import_grpc_by_fetchcontent grpc_version)
    message(STATUS "Using gRPC via FetchContent with version: ${grpc_version}")
    include(FetchContent)
    FetchContent_Declare(
        grpc
        GIT_REPOSITORY https://github.com/grpc/grpc.git
        GIT_TAG        v${grpc_version})
    FetchContent_MakeAvailable(grpc)

    set(_PROTOBUF_LIBPROTOBUF libprotobuf)
    set(_REFLECTION grpc++_reflection)
    set(_PROTOBUF_PROTOC $<TARGET_FILE:protoc>)
    set(_GRPC_GRPCPP grpc++)
    if(CMAKE_CROSSCOMPILING)
        find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
    else()
        set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>)
    endif()
endmacro()

# usage: import_grpc_by_preinstalled()
macro(import_grpc_by_preinstalled)
    message(STATUS "Using gRPC via PreInstalled.")
    set(protobuf_MODULE_COMPATIBLE TRUE)
    find_package(Protobuf CONFIG REQUIRED)
    message(STATUS "Using protobuf ${Protobuf_VERSION}")
    find_package(gRPC CONFIG REQUIRED)
    message(STATUS "Using gRPC ${gRPC_VERSION}")
    
    set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
    set(_REFLECTION gRPC::grpc++_reflection)
    if(CMAKE_CROSSCOMPILING)
        find_program(_PROTOBUF_PROTOC protoc)
    else()
        set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
    endif()
    set(_GRPC_GRPCPP gRPC::grpc++)
    if(CMAKE_CROSSCOMPILING)
        find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin)
    else()
        set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>)
    endif()
endmacro()
