# (c) 2026 Prof. Flavio ABREU ARAUJO. All rights reserved.
cmake_minimum_required(VERSION 3.15...3.27)
project(pyovf VERSION 1.0.0 LANGUAGES CXX)

# C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Find Python and pybind11
# Note: PYTHON_EXECUTABLE is passed from setup.py via -DPYTHON_EXECUTABLE=...
# Must set before find_package to ensure correct Python version is used
if(CMAKE_CROSSCOMPILING)
    # MinGW wheels for Windows (build_wheels_windows.sh): the interpreter running
    # CMake is the Linux host one, so only look for the target's headers and
    # import library, given as Python3_INCLUDE_DIR and Python3_LIBRARY.
    find_package(Python3 REQUIRED COMPONENTS Development.Module)
else()
    if(PYTHON_EXECUTABLE)
        set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
    endif()
    find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)
endif()
# pybind11 from the build environment (pyproject.toml requires it): pip's build
# isolation installs it as a Python package, where CMake does not look on its
# own. Without this, the fallback below needs git and the network at every build.
if(PYTHON_EXECUTABLE AND NOT pybind11_DIR)
    execute_process(
        COMMAND "${PYTHON_EXECUTABLE}" -m pybind11 --cmakedir
        OUTPUT_VARIABLE _pybind11_cmakedir
        OUTPUT_STRIP_TRAILING_WHITESPACE
        RESULT_VARIABLE _pybind11_result
        ERROR_QUIET
    )
    if(_pybind11_result EQUAL 0 AND EXISTS "${_pybind11_cmakedir}")
        set(pybind11_DIR "${_pybind11_cmakedir}")
    endif()
endif()
find_package(pybind11 CONFIG QUIET)

if(NOT pybind11_FOUND)
    # Fetch pybind11 if not found
    include(FetchContent)
    FetchContent_Declare(
        pybind11
        GIT_REPOSITORY https://github.com/pybind/pybind11.git
        GIT_TAG v2.11.1
    )
    FetchContent_MakeAvailable(pybind11)
endif()

# Find ovf-rw sources
set(OVF_RW_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../ovf-rw")
if(NOT EXISTS "${OVF_RW_DIR}")
    set(OVF_RW_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/pyovf/ovf-rw")
endif()

if(NOT EXISTS "${OVF_RW_DIR}/src_c++/OVF_File.cpp")
    message(FATAL_ERROR "Could not find OVF_File.cpp in ${OVF_RW_DIR}")
endif()

# Create the Python module
pybind11_add_module(_ovf_core MODULE
    src/pyovf/bindings/ovf_bindings.cpp
    ${OVF_RW_DIR}/src_c++/OVF_File.cpp
)

target_include_directories(_ovf_core PRIVATE
    ${OVF_RW_DIR}/src_c++
)

target_compile_definitions(_ovf_core PRIVATE
    BINDING  # Tells OVF_File not to delete data (Python/NumPy manages memory)
)

# Compiler-specific options
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
    target_compile_options(_ovf_core PRIVATE -Wall -Wextra -O3)
elseif(MSVC)
    target_compile_options(_ovf_core PRIVATE /W4 /O2)
endif()

# Install target
install(TARGETS _ovf_core DESTINATION pyovf)