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

# ----------------------------------------------------------------------
# Helper function to convert CMake library lists to pkg-config format
# ----------------------------------------------------------------------
function(convert_libs_to_pkgconfig output_var)
  set(result "")
  foreach(lib ${ARGN})
    # Check if it's an absolute path to a library file
    if(EXISTS "${lib}" AND lib MATCHES "\\.(a|so|dylib)$")
      get_filename_component(lib_dir "${lib}" DIRECTORY)
      get_filename_component(lib_name "${lib}" NAME_WE)
      string(REGEX REPLACE "^lib" "" lib_name "${lib_name}")
      # Only add -L if it's not a standard system path
      if(NOT lib_dir MATCHES "^/usr/lib" AND NOT lib_dir MATCHES "^/lib")
        set(result "${result} -L${lib_dir}")
      endif()
      set(result "${result} -l${lib_name}")
    else()
      # It's already a linker flag or library name
      set(result "${result} ${lib}")
    endif()
  endforeach()
  string(STRIP "${result}" result)
  set(${output_var}
      "${result}"
      PARENT_SCOPE
  )
endfunction()

# ----------------------------------------------------------------------
# Helper function to extract library info from CMake target
# ----------------------------------------------------------------------
function(get_target_lib_info target output_cflags output_clibs fallback_lib)
  # Get include directories
  get_target_property(include_dirs ${target} INTERFACE_INCLUDE_DIRECTORIES)
  if(include_dirs)
    set(${output_cflags}
        "-I${include_dirs}"
        PARENT_SCOPE
    )
  else()
    set(${output_cflags}
        ""
        PARENT_SCOPE
    )
  endif()

  # Try to get library location
  get_target_property(lib_location ${target} IMPORTED_LOCATION)
  if(NOT lib_location)
    get_target_property(lib_location ${target} LOCATION)
  endif()

  if(lib_location AND EXISTS "${lib_location}")
    get_filename_component(lib_dir "${lib_location}" DIRECTORY)
    # Only add -L if it's not a standard system path
    if(NOT lib_dir MATCHES "^/usr/lib" AND NOT lib_dir MATCHES "^/lib")
      set(${output_clibs}
          "-L${lib_dir} -l${fallback_lib}"
          PARENT_SCOPE
      )
    else()
      set(${output_clibs}
          "-l${fallback_lib}"
          PARENT_SCOPE
      )
    endif()
  else()
    # Fallback: try INTERFACE_LINK_LIBRARIES
    get_target_property(link_libs ${target} INTERFACE_LINK_LIBRARIES)
    if(link_libs)
      convert_libs_to_pkgconfig(result ${link_libs})
      set(${output_clibs}
          "${result}"
          PARENT_SCOPE
      )
    else()
      set(${output_clibs}
          "-l${fallback_lib}"
          PARENT_SCOPE
      )
    endif()
  endif()
endfunction()

# ----------------------------------------------------------------------
# pkg-config files
# ----------------------------------------------------------------------

# Set variables for pkg-config substitution
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "\${prefix}")
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
set(PACKAGE_URL "https://dkrz-sw.gitlab-pages.dkrz.de/yac/")
set(VERSION "${PROJECT_VERSION}")

# Compiler variables - use MPI compiler wrappers
set(CC "${MPI_C_COMPILER}")
if(YAC_ENABLE_FORTRAN)
  set(FC "${MPI_Fortran_COMPILER}")
  set(FCMODINC "-I")
else()
  set(FC "")
  set(FCMODINC "")
endif()

# MPI flags - empty since we're using compiler wrappers
set(MPI_CFLAGS "")
set(MPI_CLIBS "")

# YAXT flags
get_target_lib_info(yaxt::yaxt_c YAXT_CFLAGS YAXT_CLIBS "yaxt_c")

# NetCDF flags
if(YAC_ENABLE_NETCDF)
  get_target_lib_info(NetCDF::NetCDF_C NETCDF_CFLAGS NETCDF_CLIBS "netcdf")
else()
  set(NETCDF_CFLAGS "")
  set(NETCDF_CLIBS "")
endif()

# OpenMP flags
if(YAC_ENABLE_OPENMP)
  set(OPENMP_CFLAGS "${OpenMP_C_FLAGS}")
  set(OPENMP_FCLIBS "${OpenMP_Fortran_FLAGS}")
else()
  set(OPENMP_CFLAGS "")
  set(OPENMP_FCLIBS "")
endif()

# LAPACK flags
if(YAC_LAPACK_INTERFACE STREQUAL "system")
  convert_libs_to_pkgconfig(YAC_LAPACK_PKGCONF_CLIBS ${LAPACK_LIBRARIES})
elseif(YAC_LAPACK_INTERFACE STREQUAL "bundled-clapack")
  # Our own library, always use -L
  set(YAC_LAPACK_PKGCONF_CLIBS "-L\${libdir} -lyac_clapack")
else()
  set(YAC_LAPACK_PKGCONF_CLIBS "")
endif()

# libfyaml flags
if(YAC_ENABLE_MCI)
  get_target_lib_info(libfyaml::libfyaml FYAML_CFLAGS FYAML_CLIBS "fyaml")
else()
  set(FYAML_CFLAGS "")
  set(FYAML_CLIBS "")
endif()

# mtime flags (internal library) - always use -L since it's our own library
if(YAC_ENABLE_MCI)
  if(YAC_EXTERNAL_MTIME)
    get_target_lib_info(
      mtime::mtime_c YAC_MTIME_PKGCONF_CFLAGS YAC_MTIME_PKGCONF_CLIBS "mtime"
    )
  else()
    set(MTIME_CLIBS "-L\${libdir} -lyac_mtime")
    set(MTIME_CFLAGS "")
  endif()
else()
  set(MTIME_CLIBS "")
  set(MTIME_CFLAGS "")
endif()

# Additional linker flags and libraries
set(LDFLAGS "")
set(LIBS "-lm")

# Configure and install yac-core.pc
configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/yac-core.pc.in"
  "${CMAKE_BINARY_DIR}/yac-core.pc"
  @ONLY
)
install(
  FILES "${CMAKE_BINARY_DIR}/yac-core.pc"
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)

# Configure and install yac-utils.pc
configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/yac-utils.pc.in"
  "${CMAKE_BINARY_DIR}/yac-utils.pc"
  @ONLY
)
install(
  FILES "${CMAKE_BINARY_DIR}/yac-utils.pc"
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)

# Configure and install yac-mci.pc (if MCI is enabled)
if(YAC_ENABLE_MCI)
  configure_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/yac-mci.pc.in"
    "${CMAKE_BINARY_DIR}/yac-mci.pc"
    @ONLY
  )
  install(
    FILES "${CMAKE_BINARY_DIR}/yac-mci.pc"
    DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
  )
endif()
