find_package(Protobuf)
# TODO: replace with target_link_directories once released
link_directories(@TARGET_LIB_DIR@)

set(@TARGET@_INCLUDE_DIRS @TARGET_INCLUDE_DIR@)
set(@TARGET@_LIBRARIES @PROTOBUF_LIBRARY_TARGET@)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

function(generate_qtprotobuf)
    set(options)
    set(oneValueArgs OUT_DIR TARGET)
    set(multiValueArgs GENERATED_HEADERS PROTO_FILES)
    cmake_parse_arguments(generate_qtprotobuf "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    set(QtProtobuf_GENERATED ${generate_qtprotobuf_TARGET}_qtprotobuf_gen PARENT_SCOPE)
    set(QtProtobuf_GENERATED ${generate_qtprotobuf_TARGET}_qtprotobuf_gen)

    set(GEN_TARGET ${generate_qtprotobuf_TARGET}_qtprotobuf_generate)

    add_custom_target(${GEN_TARGET})

    if(NOT DEFINED QTPROTOBUF_EXECUTABLE)
        set(QTPROTOBUF_EXECUTABLE @TARGET_BIN_DIR@/@GENERATOR_TARGET@)
    endif()

    foreach(PROTO_FILE IN LISTS generate_qtprotobuf_PROTO_FILES)
        get_filename_component(BASE_DIR ${PROTO_FILE} DIRECTORY)
        set(PROTO_INCLUDES -I"${BASE_DIR}" ${PROTO_INCUDES})
    endforeach()

    if(NOT DEFINED generate_qtprotobuf_OUT_DIR)
        set(OUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
    else()
        set(OUT_DIR ${generate_qtprotobuf_OUT_DIR})
    endif()

    file(MAKE_DIRECTORY ${OUT_DIR})

    unset(QTPROTOBUF_GENERATED_SOURCES)
    unset(QTPROTOBUF_GENERATED_HEADERS)
    foreach(GENERATED_HEADER IN LISTS generate_qtprotobuf_GENERATED_HEADERS)
        get_filename_component(GENERATED_BASENAME ${GENERATED_HEADER} NAME_WE)

        list(APPEND QTPROTOBUF_GENERATED_SOURCES ${OUT_DIR}/${GENERATED_BASENAME}.cpp)
        list(APPEND QTPROTOBUF_GENERATED_HEADERS ${OUT_DIR}/${GENERATED_BASENAME}.h)
        set_property(SOURCE ${OUT_DIR}/${GENERATED_BASENAME}.cpp PROPERTY SKIP_AUTOMOC ON)
    endforeach()

    add_custom_command(TARGET ${GEN_TARGET}
            COMMAND ${Protobuf_PROTOC_EXECUTABLE}
                --@GENERATOR_TARGET@_opt=out=${OUT_DIR}
                --plugin=protoc-gen-@GENERATOR_TARGET@=${QTPROTOBUF_EXECUTABLE}
                --@GENERATOR_TARGET@_out=${OUT_DIR}
                ${PROTO_INCLUDES}
                ${PROTO_FILES}
            WORKING_DIRECTORY ${OUT_DIR}
            DEPENDS ${PROTO_FILES}
            COMMENT "Generating test headers"
    )

    qt5_wrap_cpp(MOC_SOURCES ${QTPROTOBUF_GENERATED_HEADERS})
    list(APPEND GENERATED_SOURCES ${MOC_SOURCES})

    set_source_files_properties(${QTPROTOBUF_GENERATED_SOURCES} PROPERTIES GENERATED TRUE)
    add_library(${QtProtobuf_GENERATED} ${QTPROTOBUF_GENERATED_SOURCES} ${MOC_SOURCES})
    add_dependencies(${QtProtobuf_GENERATED} ${GEN_TARGET})
    target_include_directories(${QtProtobuf_GENERATED} PRIVATE ${Qt5Core_INCLUDE_DIRS} ${Qt5Qml_INCLUDE_DIRS} ${QtProtobuf_INCLUDE_DIRS} ${QtGrpc_INCLUDE_DIRS} ${OUT_DIR})
endfunction()
