
option(SUBMODULE_CHECK "Enables checking that vendored library submodules are up to date" ON)
if(SUBMODULE_CHECK)
  find_package(Git)
  if(GIT_FOUND)
    function(check_submodule relative_path)
      execute_process(COMMAND git rev-parse "HEAD" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${relative_path} OUTPUT_VARIABLE localHead)
      execute_process(COMMAND git rev-parse "HEAD:external/${relative_path}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE checkedHead)
      string(COMPARE EQUAL "${localHead}" "${checkedHead}" upToDate)
      if (upToDate)
        message(STATUS "Submodule 'external/${relative_path}' is up-to-date")
      else()
        message(FATAL_ERROR "Submodule 'external/${relative_path}' is not up-to-date. Please update with\ngit submodule update --init --recursive\nor run cmake with -DSUBMODULE_CHECK=OFF")
      endif()

      # Extra arguments check nested submodules
      foreach(submod ${ARGN})
        execute_process(COMMAND git rev-parse "HEAD" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${relative_path}/${submod} OUTPUT_VARIABLE localHead)
        execute_process(COMMAND git rev-parse "HEAD:${submod}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${relative_path} OUTPUT_VARIABLE checkedHead)
        string(COMPARE EQUAL "${localHead}" "${checkedHead}" upToDate)
        if (NOT upToDate)
            message(FATAL_ERROR "Nested submodule '${relative_path}/${submod}' is not up-to-date. Please update with\ngit submodule update --init --recursive\nor run cmake with -DSUBMODULE_CHECK=OFF")
        endif()
      endforeach()
    endfunction ()

    message(STATUS "Checking submodules")
    check_submodule(nlohmann)
    check_submodule(cxxopts)
    check_submodule(ghc-filesystem)
    check_submodule(oxen-logging fmt spdlog)
    check_submodule(pybind11)
    check_submodule(sqlite_orm)
    check_submodule(oxen-mq)
    check_submodule(oxen-encoding)
    check_submodule(uvw)
    check_submodule(cpr)
    check_submodule(ngtcp2)
  endif()
endif()

macro(system_or_submodule BIGNAME smallname pkgconf subdir)
  option(FORCE_${BIGNAME}_SUBMODULE "force using ${smallname} submodule" OFF)
  if(NOT BUILD_STATIC_DEPS AND NOT FORCE_${BIGNAME}_SUBMODULE AND NOT FORCE_ALL_SUBMODULES)
    pkg_check_modules(${BIGNAME} ${pkgconf} IMPORTED_TARGET)
  endif()
  if(${BIGNAME}_FOUND)
    add_library(${smallname} INTERFACE)
    if(NOT TARGET PkgConfig::${BIGNAME} AND CMAKE_VERSION VERSION_LESS "3.21")
      # Work around cmake bug 22180 (PkgConfig::THING not set if no flags needed)
    else()
      target_link_libraries(${smallname} INTERFACE PkgConfig::${BIGNAME})
    endif()
    message(STATUS "Found system ${smallname} ${${BIGNAME}_VERSION}")
  else()
    message(STATUS "using ${smallname} submodule")
    add_subdirectory(${subdir})
  endif()
  if(NOT TARGET ${smallname}::${smallname})
    add_library(${smallname}::${smallname} ALIAS ${smallname})
  endif()
endmacro()

system_or_submodule(OXENC oxenc liboxenc>=1.2.0 oxen-encoding)
system_or_submodule(OXENMQ oxenmq liboxenmq>=1.2.14 oxen-mq)

set(JSON_BuildTests OFF CACHE INTERNAL "")
set(JSON_Install OFF CACHE INTERNAL "")
system_or_submodule(NLOHMANN nlohmann_json nlohmann_json>=3.7.0 nlohmann)

if (STATIC OR FORCE_SPDLOG_SUBMODULE OR FORCE_FMT_SUBMODULE)
    set(OXEN_LOGGING_FORCE_SUBMODULES ON CACHE INTERNAL "")
endif()
set(OXEN_LOGGING_SOURCE_ROOT "${PROJECT_SOURCE_DIR}" CACHE INTERNAL "")
add_subdirectory(oxen-logging)

if(WITH_HIVE)
  add_subdirectory(pybind11 EXCLUDE_FROM_ALL)
endif()

add_subdirectory(cxxopts EXCLUDE_FROM_ALL)

if(WITH_PEERSTATS)
  add_library(sqlite_orm INTERFACE)
  target_include_directories(sqlite_orm SYSTEM INTERFACE sqlite_orm/include)
  if(NOT TARGET sqlite3)
    add_library(sqlite3 INTERFACE)
    pkg_check_modules(SQLITE3 REQUIRED IMPORTED_TARGET sqlite3)
    target_link_libraries(sqlite3 INTERFACE PkgConfig::SQLITE3)
  endif()
  target_link_libraries(sqlite_orm INTERFACE sqlite3)
endif()

add_library(uvw INTERFACE)
target_include_directories(uvw INTERFACE uvw/src)
target_link_libraries(uvw INTERFACE libuv)

# ngtcp2 needs some massaging to build nicely:
include(ngtcp2_lib)
add_ngtcp2_lib()

# cpr configuration.  Ideally we'd just do this via add_subdirectory, but cpr's cmake requires
# 3.15+, and we target lower than that (and this is fairly simple to build).
if(WITH_BOOTSTRAP)
  if(NOT BUILD_STATIC_DEPS)
    find_package(CURL REQUIRED COMPONENTS HTTP HTTPS SSL)

    # CURL::libcurl wasn't added to FindCURL until cmake 3.12, so add it if necessary
    if (CMAKE_VERSION VERSION_LESS 3.12 AND NOT TARGET CURL::libcurl)
      add_library(libcurl UNKNOWN IMPORTED GLOBAL)
      set_target_properties(libcurl PROPERTIES
        IMPORTED_LOCATION ${CURL_LIBRARIES}
        INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIRS}")
      add_library(CURL_libcurl INTERFACE)
      target_link_libraries(CURL_libcurl INTERFACE libcurl)
      add_library(CURL::libcurl ALIAS CURL_libcurl)
    endif()
  endif()

  file(GLOB cpr_sources ${conf_depends} cpr/cpr/*.cpp)

  add_library(cpr STATIC EXCLUDE_FROM_ALL ${cpr_sources})
  target_link_libraries(cpr PUBLIC CURL::libcurl)
  target_include_directories(cpr PUBLIC cpr/include)
  target_compile_definitions(cpr PUBLIC CPR_CURL_NOSIGNAL)
  add_library(cpr::cpr ALIAS cpr)

  file(READ cpr/CMakeLists.txt cpr_cmake_head LIMIT 1000)
  if(cpr_cmake_head MATCHES "project\\(cpr VERSION ([0-9]+)\.([0-9]+)\.([0-9]+) LANGUAGES CXX\\)")
    set(cpr_VERSION_MAJOR ${CMAKE_MATCH_1})
    set(cpr_VERSION_MINOR ${CMAKE_MATCH_2})
    set(cpr_VERSION_PATCH ${CMAKE_MATCH_3})
    set(cpr_VERSION "${cpr_VERSION_MAJOR}.${cpr_VERSION_MINOR}.${cpr_VERSION_PATCH}")
    set(cpr_VERSION_NUM "(${cpr_VERSION_MAJOR} * 0x10000 + ${cpr_VERSION_MINOR} * 0x100 + ${cpr_VERSION_PATCH})")

    configure_file(cpr/cmake/cprver.h.in "${CMAKE_CURRENT_BINARY_DIR}/cpr_generated_includes/cpr/cprver.h")
    target_include_directories(cpr PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/cpr_generated_includes")
  else()
    message(FATAL_ERROR "Could not identify cpr submodule version!")
  endif()

endif()
