cmake_minimum_required(VERSION 3.20)
project(serial_sample CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(OpenGL_GL_PREFERENCE GLVND)

# ==============================================================================
# ЗАГРУЗКА ЗАВИСИМОСТЕЙ ЧЕРЕЗ FETCHCONTENT (ImGui и ImPlot)
# ==============================================================================
include(FetchContent)

# 1. Загрузка Dear ImGui
FetchContent_Declare(
        imgui
        GIT_REPOSITORY https://github.com/ocornut/imgui.git
        GIT_TAG        master
)
FetchContent_MakeAvailable(imgui)

# 2. Загрузка ImPlot
FetchContent_Declare(
        implot
        GIT_REPOSITORY https://github.com/epezent/implot.git
        GIT_TAG        master
)
FetchContent_MakeAvailable(implot)

# ==============================================================================
# НАСТРОЙКА ИСХОДНЫХ КОДОВ БИБЛИОТЕК
# ==============================================================================
# Исходники ImGui
set(IMGUI_SOURCES
        ${imgui_SOURCE_DIR}/imgui.cpp
        ${imgui_SOURCE_DIR}/imgui_demo.cpp
        ${imgui_SOURCE_DIR}/imgui_draw.cpp
        ${imgui_SOURCE_DIR}/imgui_tables.cpp
        ${imgui_SOURCE_DIR}/imgui_widgets.cpp
        ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp
        ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp
)

# Исходники ImPlot
set(IMPLOT_SOURCES
        ${implot_SOURCE_DIR}/implot.cpp
        ${implot_SOURCE_DIR}/implot_items.cpp
        ${implot_SOURCE_DIR}/implot_demo.cpp
)

# ==============================================================================
# ПОИСК СИСТЕМНЫХ ПАКЕТОВ
# ==============================================================================
find_package(PkgConfig REQUIRED)
find_package(OpenGL REQUIRED)
pkg_check_modules(GLFW REQUIRED glfw3)
pkg_check_modules(LIBSERIALPORT REQUIRED IMPORTED_TARGET libserialport)
find_package(Protobuf REQUIRED)
find_package(gRPC REQUIRED)

# ==============================================================================
# ГЕНЕРАЦИЯ PROTOBUF & GRPC
# ==============================================================================
set(proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/service.pb.cc")
set(proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/service.pb.h")
set(grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/service.grpc.pb.cc")
set(grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/service.grpc.pb.h")

add_custom_command(
        OUTPUT "${proto_srcs}" "${proto_hdrs}" "${grpc_srcs}" "${grpc_hdrs}"
        COMMAND ${Protobuf_PROTOC_EXECUTABLE}
        ARGS --grpc_out="${CMAKE_CURRENT_BINARY_DIR}"
        --cpp_out="${CMAKE_CURRENT_BINARY_DIR}"
        -I "${CMAKE_CURRENT_SOURCE_DIR}/proto"
        --plugin=protoc-gen-grpc=/usr/bin/grpc_cpp_plugin
        "${CMAKE_CURRENT_SOURCE_DIR}/proto/service.proto"
        DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/proto/service.proto"
)

set_source_files_properties(
        "${proto_srcs}" "${proto_hdrs}" "${grpc_srcs}" "${grpc_hdrs}"
        PROPERTIES GENERATED TRUE
)

add_library(proto_lib STATIC ${proto_srcs} ${grpc_srcs} proto/service.proto)
target_link_libraries(proto_lib PUBLIC gRPC::grpc++ ${Protobuf_LIBRARIES})
target_include_directories(proto_lib PUBLIC
        ${CMAKE_CURRENT_BINARY_DIR}
        ${Protobuf_INCLUDE_DIRS}
)

# ==============================================================================
# СБОРКА ОСНОВНОГО ПРИЛОЖЕНИЯ
# ==============================================================================
add_executable(${PROJECT_NAME} main.cpp
        ${IMGUI_SOURCES}
        ${IMPLOT_SOURCES}
        sources/SerialApp.cpp
        include/SerialApp.h
        sources/ConnectionWindow.cpp
        include/ConnectionWindow.h
        sources/PayloadWindow.cpp
        include/PayloadWindow.h
        sources/LogWindow.cpp
        include/LogWindow.h
)

target_include_directories(${PROJECT_NAME} PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
        ${CMAKE_CURRENT_BINARY_DIR}
        ${Protobuf_INCLUDE_DIRS}
        ${imgui_SOURCE_DIR}
        ${imgui_SOURCE_DIR}/backends
        ${implot_SOURCE_DIR}
        ${GLFW_INCLUDE_DIRS}
        ${OPENGL_INCLUDE_DIR}
)

target_link_libraries(${PROJECT_NAME} PRIVATE
        ${GLFW_LIBRARIES}
        OpenGL::GL
        X11
        pthread
        dl
        PkgConfig::LIBSERIALPORT
        proto_lib
)

configure_file(style/dracula.theme ${CMAKE_CURRENT_BINARY_DIR}/dracula.theme COPYONLY)


#Является частой практикой в больших проектах для поддержки
#единой схемы данныхмежду сервером и клиентом.
#Если .proto лежит в отдельном Git-репозитории на сервере
#лучше использовать FetchContent. Он корректно кэширует файлы
#и обновляет их только при смене тега или хэша коммита.
#```
#FetchContent_Declare(
#remote_proto
#GIT_REPOSITORY git@your-server.com:shared/protocols.git  # URL вашего репозитория
#GIT_TAG        main                                      # Ветка, тег или хэш коммита
#)
#FetchContent_MakeAvailable(remote_proto)
#```
#Теперь файл доступен по пути: ${remote_proto_SOURCE_DIR}/service.proto
#
#не забыть обновить команду компиляции Protobuf,
#заменив локальные пути на пути из FetchContent:
#```
#add_custom_command(
#OUTPUT "${proto_srcs}" "${proto_hdrs}" "${grpc_srcs}" "${grpc_hdrs}"
#COMMAND ${Protobuf_PROTOC_EXECUTABLE}
#ARGS --grpc_out="${CMAKE_CURRENT_BINARY_DIR}"
#--cpp_out="${CMAKE_CURRENT_BINARY_DIR}"
#-I "${remote_proto_SOURCE_DIR}"                       # Корневая папка для импортов
#--plugin=protoc-gen-grpc=/usr/bin/grpc_cpp_plugin
#"${REMOTE_PROTO_PATH}"                                 # Сам файл
#DEPENDS "${REMOTE_PROTO_PATH}"
#)
#```
