include_guard(GLOBAL)

function(indent_message header content indent_num)
  if(indent_num GREATER 0)
    string(REPEAT " " ${indent_num} indentation)
    string(REPEAT "." ${indent_num} tail)
    string(REGEX REPLACE "${tail}$" "" header "${header}")
  endif()
  message("${indentation}${header} ${content}")
endfunction()

# Print compiler's flags on best-effort. Include the abstracted
# CMake flags that we touch ourselves.
function(print_flags_per_config config indent_num)
  string(STRIP "${CMAKE_CXX_COMPILER_ARG1} ${CMAKE_CXX_FLAGS}" combined_cxx_flags)
  string(TOUPPER "${config}" config_uppercase)
  string(STRIP "${combined_cxx_flags} ${CMAKE_CXX_FLAGS_${config_uppercase}}" combined_cxx_flags)
  string(STRIP "${combined_cxx_flags} ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION}" combined_cxx_flags)
  if(CMAKE_POSITION_INDEPENDENT_CODE)
    string(JOIN " " combined_cxx_flags ${combined_cxx_flags} ${CMAKE_CXX_COMPILE_OPTIONS_PIC})
  endif()
  if(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY AND CMAKE_CXX_VISIBILITY_PRESET)
    string(JOIN " " combined_cxx_flags ${combined_cxx_flags} ${CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY}${CMAKE_CXX_VISIBILITY_PRESET})
  endif()
  get_directory_property(compile_options COMPILE_OPTIONS)
  string(JOIN " " combined_cxx_flags ${combined_cxx_flags} ${compile_options})
  indent_message("CXXFLAGS .............................." "${combined_cxx_flags}" ${indent_num})
endfunction()

function(print_configure_summary)
  message("")
  if(PROJECT_IS_TOP_LEVEL)
    message("Configure summary")
    message("=================")
  else()
    message("minisketch configure summary")
    message("============================")
  endif()
  if(BUILD_SHARED_LIBS)
    set(library_type "Shared")
  else()
    set(library_type "Static")
  endif()
  message("Library type .......................... ${library_type}")
  message("Build options:")
  if(have_disabled_fields)
    set(filed_sizes "${MINISKETCH_FIELDS}")
  else()
    set(filed_sizes "All")
  endif()
  message("  field sizes  ........................ ${filed_sizes}")
  if(HAVE_CLMUL)
    set(clmul_status "Enabled")
  else()
    set(clmul_status "Disabled")
  endif()
  message("  clmul fields ........................ ${clmul_status}")
  if(CMAKE_CXX_STANDARD GREATER_EQUAL 20)
    set(clz_status "C++20")
  elseif(HAVE_CLZ)
    set(clz_status "Compiler builtin")
  else()
    set(clz_status "Default")
  endif()
  message("  clz implementation .................. ${clz_status}")
  message("Optional binaries:")
  message("  benchmark ........................... ${MINISKETCH_BUILD_BENCHMARK}")
  message("  tests ............................... ${MINISKETCH_BUILD_TESTS}")
  message("")
  if(CMAKE_CROSSCOMPILING)
    set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")
  else()
    set(cross_status "FALSE")
  endif()
  message("Cross compiling ....................... ${cross_status}")
  message("C++ compiler .......................... ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}, ${CMAKE_CXX_COMPILER}")
  get_property(_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
  if(_is_multi_config)
    list(JOIN CMAKE_CONFIGURATION_TYPES ", " configs)
    message("Available build configurations ........ ${configs}")
    if(CMAKE_GENERATOR MATCHES "Visual Studio")
      set(default_config "Debug")
    else()
      list(GET CMAKE_CONFIGURATION_TYPES 0 default_config)
    endif()
    message("Default build configuration ........... ${default_config}")
    foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES)
      message("'${config}' build configuration:")
      print_flags_per_config("${config}" 2)
    endforeach()
  else()
    message("CMAKE_BUILD_TYPE ...................... ${CMAKE_BUILD_TYPE}")
    print_flags_per_config("${CMAKE_BUILD_TYPE}" 0)
  endif()
  unset(_is_multi_config)

  message([=[

NOTE: The summary above may not exactly match the final applied build flags
      if any additional CMAKE_* or environment variables have been modified.
      To see the exact flags applied, build with the --verbose option.]=]
  )

  if(have_disabled_fields AND PROJECT_IS_TOP_LEVEL)
    message("")
    message(WARNING
      "Only compiling in support for field sizes: ${MINISKETCH_FIELDS}\n"
      "This means the library will lack support for other field sizes entirely.\n"
    )
  endif()
  message("")
endfunction()
