# SPDX-License-Identifier: MPL-2.0

find_package(
  Python 3.10
  COMPONENTS Interpreter Development.Module
  REQUIRED)
set(PYBIND11_FINDPYTHON ON) # Needed for RH8

# Download or find pybind11 depending on configuration
if(AARE_FETCH_PYBIND11)
  FetchContent_Declare(
    pybind11
    GIT_REPOSITORY https://github.com/pybind/pybind11
    GIT_TAG v3.0.3
    GIT_SHALLOW TRUE)
  FetchContent_MakeAvailable(pybind11)
else()
  find_package(pybind11 3.0.3 REQUIRED)
endif()

# The compiled python extension: one translation unit per binding area so they
# compile in parallel; see src/module.cpp for the registration order.
#
# Without NO_EXTRAS pybind11 links pybind11::lto, which forces full LTO on the
# extension regardless of the target's INTERPROCEDURAL_OPTIMIZATION property.
# LTO cannot reach aare_core (a plain static library) and the templated hot
# paths are already compiled at -O3 inside the extension, so it only adds a long
# single-threaded link step. With NO_EXTRAS the standard target property decides
# (off by default); the other extras are re-added below.
pybind11_add_module(
  _aare # name of the module
  NO_EXTRAS
  src/module.cpp
  src/bind_io.cpp
  src/bind_hist.cpp
  src/bind_pedestal.cpp
  src/bind_fit.cpp
  src/bind_eta.cpp
  src/bind_cluster_2x2.cpp
  src/bind_cluster_3x3.cpp
  src/bind_cluster_5x5.cpp
  src/bind_cluster_7x7.cpp
  src/bind_cluster_9x9.cpp)

set_target_properties(_aare PROPERTIES LIBRARY_OUTPUT_DIRECTORY
                                       ${CMAKE_BINARY_DIR})
target_link_libraries(_aare PRIVATE aare_core aare_compiler_flags)

# The pybind11_add_module extras that NO_EXTRAS skipped, LTO excepted
if(MSVC)
  target_link_libraries(_aare PRIVATE pybind11::windows_extras) # /bigobj, /MP
elseif(CMAKE_BUILD_TYPE)
  string(TOUPPER "${CMAKE_BUILD_TYPE}" _aare_build_type)
  if(NOT _aare_build_type MATCHES "DEBUG|RELWITHDEBINFO|NONE")
    pybind11_strip(_aare) # strip symbols from optimized builds
  endif()
endif()

target_include_directories(
  _aare SYSTEM
  PRIVATE $<TARGET_PROPERTY:aare::Minuit2,INTERFACE_INCLUDE_DIRECTORIES>)

# List of python files to be copied to the build directory
set(PYTHON_FILES
    aare/__init__.py
    aare/_version.py
    aare/CtbRawFile.py
    aare/ClusterFinder.py
    aare/ClusterVector.py
    aare/Cluster.py
    aare/FastPedestal.py
    aare/Pedestal.py
    aare/calibration.py
    aare/factory.py
    aare/experimental.py
    aare/RawFile.py
    aare/transform.py
    aare/ScanParameters.py
    aare/utils.py)

# Copy the python files to the build directory
foreach(FILE ${PYTHON_FILES})
  configure_file(${FILE} ${CMAKE_BINARY_DIR}/${FILE})
endforeach(FILE ${PYTHON_FILES})

set_target_properties(_aare PROPERTIES LIBRARY_OUTPUT_DIRECTORY
                                       ${CMAKE_BINARY_DIR}/aare)

set(PYTHON_EXAMPLES examples/play.py examples/fits.py)

# Copy the python examples to the build directory
foreach(FILE ${PYTHON_EXAMPLES})
  configure_file(${FILE} ${CMAKE_BINARY_DIR}/${FILE})
  message(STATUS "Copying ${FILE} to ${CMAKE_BINARY_DIR}/${FILE}")
endforeach(FILE ${PYTHON_EXAMPLES})

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../VERSION
               ${CMAKE_BINARY_DIR}/aare/VERSION)
if(AARE_INSTALL_PYTHONEXT)
  install(
    TARGETS _aare
    EXPORT "${TARGETS_EXPORT_NAME}"
    LIBRARY DESTINATION aare COMPONENT python)

  install(
    FILES ${PYTHON_FILES}
    DESTINATION aare
    COMPONENT python)
  install(
    FILES ../VERSION
    DESTINATION aare
    COMPONENT python)
endif()
