# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.16)

# Version is single-sourced from the public header (see include/etree/etree.hpp).
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/include/etree/etree.hpp" _etree_hpp)
string(REGEX MATCH "ETREE_VERSION_MAJOR ([0-9]+)" _ "${_etree_hpp}")
set(_etree_major "${CMAKE_MATCH_1}")
string(REGEX MATCH "ETREE_VERSION_MINOR ([0-9]+)" _ "${_etree_hpp}")
set(_etree_minor "${CMAKE_MATCH_1}")
string(REGEX MATCH "ETREE_VERSION_PATCH ([0-9]+)" _ "${_etree_hpp}")
set(_etree_patch "${CMAKE_MATCH_1}")
project(etree VERSION ${_etree_major}.${_etree_minor}.${_etree_patch} LANGUAGES CXX)

add_library(etree INTERFACE)
add_library(etree::etree ALIAS etree)
target_compile_features(etree INTERFACE cxx_std_17)
target_include_directories(etree INTERFACE
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)

find_package(Threads REQUIRED)
target_link_libraries(etree INTERFACE Threads::Threads)

# Eigen: use an installed copy if available, otherwise download a pinned release.
find_package(Eigen3 3.3 QUIET NO_MODULE)
if(NOT TARGET Eigen3::Eigen)
    option(ETREE_FETCH_EIGEN "Download Eigen if no installed copy is found" ON)
    if(NOT ETREE_FETCH_EIGEN)
        message(FATAL_ERROR
            "etree requires Eigen3. Install it (e.g. libeigen3-dev) or enable ETREE_FETCH_EIGEN.")
    endif()
    if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
        cmake_policy(SET CMP0135 NEW)
    endif()
    include(FetchContent)
    FetchContent_Declare(eigen3_src
        URL https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz
        URL_HASH SHA256=8586084f71f9bde545ee7fa6d00288b264a2b7ac3607b974e54d13e7162c1c72)
    FetchContent_GetProperties(eigen3_src)
    if(NOT eigen3_src_POPULATED)
        FetchContent_Populate(eigen3_src)
    endif()
    # Eigen is header-only: point an imported target at the extracted sources
    # instead of running Eigen's own build system.
    add_library(Eigen3::Eigen INTERFACE IMPORTED)
    set_target_properties(Eigen3::Eigen PROPERTIES
        INTERFACE_INCLUDE_DIRECTORIES "${eigen3_src_SOURCE_DIR}")
    message(STATUS "etree: using downloaded Eigen 3.4.0 (${eigen3_src_SOURCE_DIR})")
endif()
target_link_libraries(etree INTERFACE Eigen3::Eigen)

if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
    option(ETREE_BUILD_TESTS "Build etree tests" ON)
    option(ETREE_BUILD_EXAMPLES "Build etree examples" ON)
else()
    option(ETREE_BUILD_TESTS "Build etree tests" OFF)
    option(ETREE_BUILD_EXAMPLES "Build etree examples" OFF)
endif()

if(ETREE_BUILD_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()

if(ETREE_BUILD_EXAMPLES)
    add_subdirectory(examples)
endif()

option(ETREE_BUILD_PYTHON "Build the etree Python bindings (pybind11 via FetchContent)" OFF)
if(ETREE_BUILD_PYTHON)
    add_subdirectory(bindings)
endif()

# ------------------------- Installation / CMake package export -------------------------
# Default ON when built standalone, OFF as a subproject and OFF inside pip
# builds (scikit-build-core would otherwise install the headers into the wheel).
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR AND NOT SKBUILD)
    set(ETREE_INSTALL_DEFAULT ON)
else()
    set(ETREE_INSTALL_DEFAULT OFF)
endif()
option(ETREE_INSTALL "Generate install and CMake package export rules" ${ETREE_INSTALL_DEFAULT})

if(ETREE_INSTALL)
    include(GNUInstallDirs)
    include(CMakePackageConfigHelpers)

    install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
    install(TARGETS etree EXPORT etreeTargets)
    install(EXPORT etreeTargets
        FILE etreeTargets.cmake
        NAMESPACE etree::
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/etree)

    configure_package_config_file(
        ${CMAKE_CURRENT_SOURCE_DIR}/cmake/etreeConfig.cmake.in
        ${CMAKE_CURRENT_BINARY_DIR}/etreeConfig.cmake
        INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/etree)
    write_basic_package_version_file(
        ${CMAKE_CURRENT_BINARY_DIR}/etreeConfigVersion.cmake
        VERSION ${PROJECT_VERSION}
        COMPATIBILITY SameMajorVersion
        ARCH_INDEPENDENT)
    install(FILES
        ${CMAKE_CURRENT_BINARY_DIR}/etreeConfig.cmake
        ${CMAKE_CURRENT_BINARY_DIR}/etreeConfigVersion.cmake
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/etree)
    install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
endif()
