set(BUILD_SHARED_LIBS OFF)

if (MSVC)
  add_compile_options(-wd5045) #Disable warning about Spectre mitigation
endif()

function(add_subdirectory_compat)
    #
    # This is for CMake 4.0 compatibility.
    #
    # CMake 4.0 drops support CMake policies below 3.5 and some of our dependencies
    # declare their minimum required version as 3.4, and CMake 4.0 is not happy
    # with that. The CMAKE_POLICY_VERSION_MINIMUM option allows us to override that
    # without having to touch the dependency's source code.
    #
    # https://cmake.org/cmake/help/latest/variable/CMAKE_POLICY_VERSION_MINIMUM.html
    set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
    add_subdirectory(${ARGV})
endfunction()

# Generates gRPC and protobuf C++ sources and headers from the given .proto files
#
# generate_grpc_cpp (<SRCS> <DEST> [<ARGN>...])
#
#  SRCS - output list of autogenerated source files
#  DEST - the output directory where the autogenerated files will be created in
#  ARGN - the .proto files
#
function(generate_grpc_cpp SRCS DEST)
  if (NOT ARGN)
    message(SEND_ERROR "Error: generate_grpc_cpp() called without any proto files")
    return()
  endif ()

  set(${SRCS})
  foreach (FIL ${ARGN})
    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
    get_filename_component(FIL_WE ${FIL} NAME_WE)
    get_filename_component(FIL_DIR ${ABS_FIL} DIRECTORY)

    list(APPEND ${SRCS} "${DEST}/${FIL_WE}.grpc.pb.cc")
    list(APPEND HDRS "${DEST}/${FIL_WE}.grpc.pb.h")
    list(APPEND ${SRCS} "${DEST}/${FIL_WE}.pb.cc")
    list(APPEND HDRS "${DEST}/${FIL_WE}.pb.h")

    add_custom_command(
      OUTPUT "${DEST}/${FIL_WE}.grpc.pb.cc"
      "${DEST}/${FIL_WE}.grpc.pb.h"
      "${DEST}/${FIL_WE}.pb.cc"
      "${DEST}/${FIL_WE}.pb.h"
      COMMAND $<TARGET_FILE:protobuf::protoc>
      ARGS --grpc_out=${DEST} --cpp_out=${DEST} --proto_path=${FIL_DIR} --proto_path=${grpc_SOURCE_DIR}/third_party/protobuf/src --plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin> ${ABS_FIL}
      DEPENDS ${ABS_FIL}
      COMMENT "Running gRPC C++ protocol buffer compiler on ${FIL}"
      VERBATIM)
  endforeach ()

  set_source_files_properties(${${SRCS}} ${HDRS} PROPERTIES GENERATED TRUE)
  set(${SRCS} ${${SRCS}} PARENT_SCOPE)
endfunction()

add_library(gRPC INTERFACE)

target_link_libraries(gRPC INTERFACE
  gRPC::grpc++
  protobuf::libprotobuf)

if (NOT MSVC)
  target_compile_options(gRPC INTERFACE "-Wno-unused-parameter" "-Wno-non-virtual-dtor" "-Wno-pedantic")
endif ()

# YAML C++
# Disable tests here to avoid double-including gtest
option(YAML_CPP_BUILD_TOOLS OFF)
option(YAML_CPP_BUILD_CONTRIB OFF)
option(YAML_CPP_BUILD_TESTS OFF)

add_subdirectory_compat(yaml-cpp EXCLUDE_FROM_ALL)
set_target_properties(yaml-cpp PROPERTIES POSITION_INDEPENDENT_CODE ON)

add_library(yaml INTERFACE)

target_include_directories(yaml INTERFACE
  ${CMAKE_CURRENT_SOURCE_DIR}/yaml-cpp/include)

target_link_libraries(yaml INTERFACE
  yaml-cpp)

include(ExternalProject)

# QEMU itself
if (APPLE AND "qemu" IN_LIST MULTIPASS_BACKENDS)
    add_subdirectory(qemu)
endif ()

if(MSVC)
  set(JSONCPP_WITH_PKGCONFIG_SUPPORT OFF CACHE BOOL "Disable pkgconfig in jsoncpp" FORCE)
  set(JSONCPP_WITH_POST_BUILD_UNITTEST OFF CACHE BOOL "Disable unit tests in jsoncpp" FORCE)
  set(JSONCPP_WITH_TESTS OFF CACHE BOOL "Disable test executables in jsoncpp lib" FORCE)
  add_subdirectory(jsoncpp)
endif()

# libssh config
add_subdirectory(libssh)

# premock header only library to mock c-functions
add_library(premock INTERFACE)
target_include_directories(premock INTERFACE
  ${CMAKE_CURRENT_SOURCE_DIR}/premock)

# scope_guard header only library
add_library(scope_guard INTERFACE)
target_include_directories(scope_guard INTERFACE
  ${CMAKE_CURRENT_SOURCE_DIR}/scope_guard)
target_compile_definitions(scope_guard INTERFACE
  SG_REQUIRE_NOEXCEPT_IN_CPP17)

# semver library
add_subdirectory_compat(semver EXCLUDE_FROM_ALL)
target_include_directories(semver INTERFACE
  ${CMAKE_CURRENT_SOURCE_DIR}/semver/include)
set_target_properties(semver PROPERTIES POSITION_INDEPENDENT_CODE ON)

# xz-decoder config
add_subdirectory(xz-decoder EXCLUDE_FROM_ALL)
