cmake_minimum_required(VERSION 3.30)
cmake_policy(SET CMP0076 NEW) # Ensure target_sources converts relative paths
cmake_policy(SET CMP0017 NEW) # Prefer cmake's own files for include/find_package before CMAKE_MODULE_PATH

list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}/cmake")

set(READOUT_BUILD_ON_CONDA OFF CACHE BOOL "Set to ON to build for conda")
set(READOUT_USE_CONAN ON CACHE BOOL "Use Conan to manage dependencies") # Set to OFF to use system libraries
set(READOUT_BUILD_TESTS ON CACHE BOOL "Build test binary")
set(READOUT_DOCS_ONLY OFF CACHE BOOL "Configure only the documentation target (no dependencies, no compiled targets)")

if (READOUT_DOCS_ONLY)
    # Documentation needs only the version string and Doxygen: skip dependency
    # resolution and every compiled target so a bare runner can configure.
    set(READOUT_USE_CONAN OFF)
    set(READOUT_BUILD_TESTS OFF)
endif()

if (READOUT_USE_CONAN)
    set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES "${CMAKE_CURRENT_LIST_DIR}/cmake/conan_provider.cmake")
endif()

# Read the version of readout (from the VERSION file and git metadata);
# generates version.hpp in ${CMAKE_BINARY_DIR}/gen
include(check)
checkSetup(READOUT)
message(STATUS "Build Readout v${READOUT_VERSION} with type ${CMAKE_BUILD_TYPE}")
project(Readout LANGUAGES C CXX VERSION "${READOUT_VERSION}")

set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(GNUInstallDirs)

# The build tree mirrors the install layout (bin/, lib/, include/, share/Readout)
# so that the self-locating readout-config resolves the same baked relative paths
# whether it runs from the build tree or an installed prefix. Multi-config
# generators (Visual Studio) would otherwise add per-config subdirectories
# (bin/Debug/...), breaking those relative paths — collapse them: one
# configuration per build tree.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
foreach(READOUT_CFG IN ITEMS Debug Release RelWithDebInfo MinSizeRel)
    string(TOUPPER "${READOUT_CFG}" READOUT_CFG_UP)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${READOUT_CFG_UP} "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${READOUT_CFG_UP} "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${READOUT_CFG_UP} "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
endforeach()

add_definitions(-DUSE_HIGHFIVE)
if (MSVC)
    # warning level 4 -- add /WX for all warnings as errors
    add_compile_options(/W4)
    # suppress MSVC warning C4996 about 'localtime' vs 'localtime_s'
    add_definitions(-D_CRT_SECURE_NO_WARNINGS)
    # Allow UTF-8 identifiers https://stackoverflow.com/a/47704050
    add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
    add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
    # Prevent Windows.h from defining its own min and max macros
    add_definitions(-DNOMINMAX)
elseif(APPLE)
    add_compile_options(-Wall -Wextra -pedantic)
    if (READOUT_BUILD_ON_CONDA)
        # Enable use of, e.g. std::filesystem::path on macOS under Conda:
        # https://conda-forge.org/docs/maintainer/knowledge_base/#newer-c-features-with-old-sdk
        add_definitions(-D_LIBCPP_DISABLE_AVAILABILITY)
    endif()
else()
    add_compile_options(-Wall -Wextra -pedantic)
endif()

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Debug)
endif(NOT CMAKE_BUILD_TYPE)
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
    add_definitions(-DDEBUG)
endif()

set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# With GCC 10+ the interprocedural optimization only adds to compilation time without improving performance
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)

if (READOUT_BUILD_TESTS)
    include(CTest)
endif()

if (NOT READOUT_DOCS_ONLY)
    # The library, CLI tools, McStas components, and install rules:
    add_subdirectory(readout_core)

    # The test suite lives at the repository root (mcpl-style): it exercises the
    # readout_core targets but is not part of any installed package.
    if (READOUT_BUILD_TESTS)
        add_subdirectory(test)
    endif()
endif()

find_package(Doxygen QUIET)
if (DOXYGEN_FOUND)
    find_package(Python3 COMPONENTS Interpreter REQUIRED)
    configure_file(
        "${CMAKE_CURRENT_LIST_DIR}/docs/Doxyfile.in"
        "${CMAKE_BINARY_DIR}/Doxyfile"
        @ONLY
    )
    add_custom_target(docs
        COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_LIST_DIR}/docs/extract_comp_docs.py"
                "${CMAKE_CURRENT_LIST_DIR}/readout_core/components"
                "${CMAKE_BINARY_DIR}/docs/generated"
        COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile"
        WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
        COMMENT "Generating static HTML documentation with Doxygen"
        VERBATIM
    )
else()
    message(STATUS "Doxygen not found: docs target will not be available")
endif()
