set(${upperName}_MODULE_DIR $${CMAKE_CURRENT_LIST_DIR})

# Determine target processor name
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x64|x86_64)")
    SET(${upperName}_CPU_NAME "x86_64")
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64|ARM64EC|arm64ec|ARM64E|arm64e)")
    SET(${upperName}_CPU_NAME "aarch64")
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM|armv7hl|armv7l|armv7)")
    SET(${upperName}_CPU_NAME "armv7hl")
ELSE()
    MESSAGE(FATAL_ERROR "Unsupported architecture \"$${CMAKE_SYSTEM_PROCESSOR}\"")
ENDIF()
message(STATUS "Target CPU Name: $${${upperName}_CPU_NAME}" )

set(${name}_DEPENDENCY_LIST ${dependencies})
foreach (dependency $${${name}_DEPENDENCY_LIST})
  find_package($${dependency} REQUIRED)
endforeach()

function(define_imported_target libraries headers executables)
  set(common_lib_name ${name}::${name})

  add_library($${common_lib_name} INTERFACE IMPORTED)
  set_target_properties($${common_lib_name} PROPERTIES
    INTERFACE_INCLUDE_DIRECTORIES $${headers}
  )

  foreach (file $${libraries})
    get_filename_component(lib_name $${file} NAME)
    get_filename_component(lib_name_stem $${file} NAME_WE)

    set(target_name ${name}_$${lib_name_stem}_target)

    add_library($${target_name} SHARED IMPORTED)
    set_target_properties($${target_name} PROPERTIES
      IMPORTED_LOCATION "$${file}"
    )
    target_link_libraries($${common_lib_name} INTERFACE $${target_name})
  endforeach()

  foreach (dependency $${${name}_DEPENDENCY_LIST})
    set(dependency_task $${dependency}::$${dependency})
    target_link_libraries($${common_lib_name} INTERFACE $${dependency_task})
    add_dependencies($${common_lib_name} $${dependency_task})
  endforeach()

  set(libs_path $${${upperName}_MODULE_DIR}/$${${upperName}_CPU_NAME})

  set(copy_lib_name ${name}_copy_lib)
  add_custom_target($${copy_lib_name})
  FILE (GLOB_RECURSE LISTS_${name}_LIBS_DIR LIST_DIRECTORIES false $${libs_path}/*)
  FOREACH (file $${LISTS_${name}_LIBS_DIR})
      file(RELATIVE_PATH file_name $${libs_path} $${file})
      add_custom_command(TARGET $${copy_lib_name} POST_BUILD
          COMMAND $${CMAKE_COMMAND} -E copy
          $${file}
          $${ROOT_PROJECT_BINARY_DIR}/bundle/lib/$${file_name})
  ENDFOREACH(file)
  add_dependencies($${common_lib_name} $${copy_lib_name})

  FOREACH (FILE $${executables})
      install(FILES $${FILE} DESTINATION $${CMAKE_INSTALL_LIBEXECDIR})
  ENDFOREACH(FILE)

  set(${name}_FOUND 1 CACHE INTERNAL "${name} found" FORCE)
  set(${name}_LIBRARIES "$${libraries}"
      CACHE STRING "Path to ${name} library" FORCE)
  set(${name}_INCLUDES "$${headers}"
      CACHE STRING "Path to ${name} headers" FORCE)
  set(${name}_EXECUTABLES "$${executables}"
      CACHE STRING "Path to ${name} executable files" FORCE)
  mark_as_advanced(FORCE ${name}_LIBRARIES)
  mark_as_advanced(FORCE ${name}_INCLUDES)
  mark_as_advanced(FORCE ${name}_EXECUTABLES)

  set_property(GLOBAL PROPERTY ${name}_PROPERTY_LIBS_PATH $${libs_path})
  set_property(GLOBAL PROPERTY ${name}_PROPERTY_INCLUDE_PATH $${headers})

endfunction()

if (${name}_LIBRARIES AND ${name}_INCLUDES AND ${name}_EXECUTABLES)
  define_imported_target("$${${name}_LIBRARIES}" "$${${name}_INCLUDES}" "$${${name}_EXECUTABLES}")
  return()
endif()

set(${name}_LIBRARY_LIST ${libraries})
foreach (file $${${name}_LIBRARY_LIST})
  list(APPEND ${name}_LIBRARIES_PATH $${${upperName}_MODULE_DIR}/$${${upperName}_CPU_NAME}/$${file})
endforeach()

set(${name}_EXECUTABLES_LIST ${executables})
foreach (file $${${name}_EXECUTABLES_LIST})
  list(APPEND ${name}_EXECUTABLES_PATH $${${upperName}_MODULE_DIR}/libexec/$${${upperName}_CPU_NAME}/$${file})
endforeach()

set(${name}_HEADER_PATH $${${upperName}_MODULE_DIR}/include)

# Returning the final results
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
  ${name} DEFAULT_MSG "${name}_LIBRARIES_PATH" "${name}_HEADER_PATH"
)

if (${name}_FOUND)
  define_imported_target("$${${name}_LIBRARIES_PATH}" "$${${name}_HEADER_PATH}" "$${${name}_EXECUTABLES_PATH}")
elseif(${name}_FIND_REQUIRED)
  message(FATAL_ERROR "Required ${name} library not found")
endif()
