# Copyright (c) 2025 The YAC Authors
#
# SPDX-License-Identifier: BSD-3-Clause

# ----------------------------------------------------------------------
# Public header aggregation (yac_core.h)
# ----------------------------------------------------------------------
set(yac_core_h_headers
    core_version.h
    yac_mpi.h
    yac_types.h
    grids/grid_cell.h
    grids/basic_grid_data.h
    location.h
    field_data.h
    grids/basic_grid.h
    grids/dist_grid.h
    interpolation/interp_grid.h
    point_selection.h
    instrument.h
    interpolation/methods/interp_method.h
    interpolation/methods/interp_method_avg.h
    interpolation/methods/interp_method_check.h
    interpolation/methods/interp_method_config.h
    interpolation/methods/interp_method_conserv.h
    interpolation/methods/interp_method_creep.h
    interpolation/methods/interp_method_ncc.h
    interpolation/methods/interp_method_nnn.h
    interpolation/methods/interp_method_dnn.h
    interpolation/methods/interp_method_fixed.h
    interpolation/methods/interp_method_file.h
    interpolation/methods/interp_method_hcsbb.h
    interpolation/methods/interp_method_spmap.h
    interpolation/methods/interp_method_callback.h
    interpolation/interp_stack_config.h
    interpolation/interpolation.h
    interpolation/interp_weights.h
    interpolation/interpolation_gen_config.h
    collection_selection.h
    yac_assert.h
    io_utils.h
    ppm/symprefix.h
    ppm/core.h
)

# Path of the generated aggregated header.
set(YAC_CORE_H "${CMAKE_CURRENT_BINARY_DIR}/yac_core.h")

# ----------------------------------------------------------------------
# Generate yac_core.h using the common script
# ----------------------------------------------------------------------
add_custom_command(
  OUTPUT ${YAC_CORE_H}
  COMMAND
    ${CMAKE_COMMAND} "-D OUTPUT_FILE=${YAC_CORE_H}"
    "-D HEADER_FILES=${yac_core_h_headers}" "-D HEADER_GUARD=YAC_CORE_H"
    "-P ${CMAKE_SOURCE_DIR}/cmake/Scripts/generate_yac_public_header.cmake"
  DEPENDS ${yac_core_h_headers}
  COMMENT "Generating aggregated public header yac_core.h"
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  VERBATIM
)

# Ensure the header is generated before the core library is built.
add_custom_target(yac_core_h ALL DEPENDS ${YAC_CORE_H})

add_library(
  yac_core
  area.c
  bnd_circle.c
  bnd_triangle.c
  check_overlap.c
  clipping.c
  collection_selection.c
  core_version.c
  ensure_array_size.c
  field_data.c
  field_data_set.c
  grids/basic_grid.c
  grids/basic_grid_data.c
  grids/dist_grid.c
  grids/grid_cell.c
  grids/grid_cloud.c
  grids/grid_curve2d.c
  grids/grid_reg2d.c
  grids/grid_reg2d_common.c
  grids/grid_reg2d_common.h
  grids/grid_reg2d_rot.c
  grids/grid_unstruct.c
  instrument.c
  interpolation/interp_grid.c
  interpolation/interp_stack_config.c
  interpolation/interp_weights.c
  interpolation/interpolation.c
  interpolation/interpolation_exchange.c
  interpolation/interpolation_gen_config.c
  interpolation/interpolation_utils.c
  interpolation/methods/interp_method.c
  interpolation/methods/interp_method_avg.c
  interpolation/methods/interp_method_callback.c
  interpolation/methods/interp_method_check.c
  interpolation/methods/interp_method_config.c
  interpolation/methods/interp_method_conserv.c
  interpolation/methods/interp_method_creep.c
  interpolation/methods/interp_method_dnn.c
  interpolation/methods/interp_method_file.c
  interpolation/methods/interp_method_fixed.c
  interpolation/methods/interp_method_hcsbb.c
  interpolation/methods/interp_method_ncc.c
  interpolation/methods/interp_method_nnn.c
  interpolation/methods/interp_method_spmap.c
  interpolation/methods/interp_method_utils.c
  parameter/param.c
  parameter/param_bool.c
  parameter/param_angle.c
  parameter/param_dble.c
  parameter/param_distance.c
  parameter/param_enum.c
  parameter/param_int.c
  parameter/param_list.c
  parameter/param_oneof.c
  parameter/param_str.c
  parameter/param_struct.c
  interpolation/operators/interp_operator.c
  interpolation/operators/interp_operator_direct.c
  interpolation/operators/interp_operator_direct_mf.c
  interpolation/operators/interp_operator_fixed.c
  interpolation/operators/interp_operator_sum_mvp_at_src.c
  interpolation/operators/interp_operator_sum_mvp_at_tgt.c
  intersection.c
  interval_tree.c
  io_utils.c
  location.c
  mergesort.c
  point_selection.c
  ppm/core.c
  ppm/xmalloc.c
  ppm/xstdio.c
  proc_sphere_part.c
  quicksort.c
  remote_point.c
  sphere_part.c
  utils_core.c
  yac_lapack_interface.c
  yac_mpi.c
  yac_xmap.c
)

target_compile_features(yac_core PRIVATE c_std_99 c_restrict c_variadic_macros)

set_target_properties(yac_core PROPERTIES POSITION_INDEPENDENT_CODE TRUE)

add_dependencies(yac_core yac_core_h)

# Make the generated header visible to any target that links against core.
target_include_directories(
  yac_core
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> # original source headers
    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> # directory containing the
    # generated yac_core.h
    $<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/src> # needed for yac_config.h
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

target_link_libraries(
  yac_core
  PRIVATE LAPACK::LAPACK yaxt::yaxt_c
  PUBLIC m MPI::MPI_C
)

if(YAC_ENABLE_NETCDF)
  target_link_libraries(yac_core PRIVATE NetCDF::NetCDF_C)
endif()

if(YAC_ENABLE_OPENMP)
  target_link_libraries(yac_core PRIVATE OpenMP::OpenMP_C)
endif()

if(YAC_ENABLE_FORTRAN)
  target_sources(yac_core PRIVATE yac_core.F90)
  install(
    FILES ${CMAKE_CURRENT_BINARY_DIR}/yac_core.mod
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
  )
endif()

# Install public headers
install(FILES ${YAC_CORE_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
