# Copyright (c) 2014 Thomas Heller
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

include(CMakePackageConfigHelpers)

set(CMAKE_DIR "cmake-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" CACHE STRING "directory (in share), where to put FindHPX cmake module")

write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${HPX_PACKAGE_NAME}/${HPX_PACKAGE_NAME}ConfigVersion.cmake"
  VERSION ${HPX_VERSION}
  COMPATIBILITY AnyNewerVersion
)

export(TARGETS ${HPX_EXPORT_TARGETS}
  FILE "${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${HPX_PACKAGE_NAME}/HPXTargets.cmake"
#  NAMESPACE hpx::
)

# Generate library list for pkg config ...
set(_is_debug FALSE)
set(_is_release FALSE)
foreach(lib ${HPX_LIBRARIES})
  if(lib STREQUAL "debug")
    set(_is_debug TRUE)
    set(_is_release FALSE)
  elseif(lib STREQUAL "optimized")
    set(_is_debug FALSE)
    set(_is_release TRUE)
  elseif(lib STREQUAL "general")
    set(_is_debug FALSE)
    set(_is_release FALSE)
  else()
    if(NOT EXISTS "${lib}" AND NOT "${lib}" MATCHES "^-")
      set(lib "-l${lib}")
    endif()
    if(_is_debug)
      set(HPX_PKG_DEBUG_LIBRARIES "${HPX_PKG_DEBUG_LIBRARIES} ${lib}")
    elseif(_is_release)
      set(HPX_PKG_LIBRARIES "${HPX_PKG_LIBRARIES} ${lib}")
    else()
      set(HPX_PKG_LIBRARIES "${HPX_PKG_LIBRARIES} ${lib}")
      set(HPX_PKG_DEBUG_LIBRARIES "${HPX_PKG_DEBUG_LIBRARIES} ${lib}")
    endif()
    set(_is_debug FALSE)
    set(_is_release FALSE)
  endif()
endforeach()

set(HPX_PKG_LIBRARY_DIR "")
foreach(dir ${HPX_LIBRARY_DIR})
  set(HPX_PKG_LIBRARY_DIR "${HPX_PKG_LIBRARY_DIR} -L${dir}")
endforeach()

if(HPX_WITH_STATIC_LINKING)
  set(HPX_PKG_LIBRARIES_BAZEL "${HPX_CONF_PREFIX}/lib/libhpx.a ${HPX_PKG_LIBRARIES}")
  set(HPX_PKG_DEBUG_LIBRARIES_BAZEL "${HPX_CONF_PREFIX}/lib/libhpxd.a ${HPX_PKG_DEBUG_LIBRARIES}")
  set(HPX_CONF_LIBRARIES "general;hpx;${HPX_LIBRARIES}")
  set(HPX_PKG_LIBRARIES "\${libdir}/libhpx.a ${HPX_PKG_LIBRARIES}")
  set(HPX_PKG_DEBUG_LIBRARIES "\${libdir}/libhpxd.a ${HPX_PKG_DEBUG_LIBRARIES}")
else()
  set(HPX_CONF_LIBRARIES "general;hpx_init;general;hpx;${HPX_LIBRARIES}")
  if(APPLE)
    set(HPX_PKG_LIBRARIES_BAZEL "${HPX_CONF_PREFIX}/lib/libhpx_init.a ${HPX_CONF_PREFIX}/lib/libhpx.dylib ${HPX_PKG_LIBRARIES}")
    set(HPX_PKG_DEBUG_LIBRARIES_BAZEL "${HPX_CONF_PREFIX}/lib/libhpx_initd.a ${HPX_CONF_PREFIX}/lib/libhpxd.dylib ${HPX_PKG_DEBUG_LIBRARIES}")
    set(HPX_PKG_LIBRARIES "\${libdir}/libhpx_init.a \${libdir}/libhpx.dylib ${HPX_PKG_LIBRARIES}")
    set(HPX_PKG_DEBUG_LIBRARIES "\${libdir}/libhpx_initd.a \${libdir}/libhpxd.dylib ${HPX_PKG_DEBUG_LIBRARIES}")
  else()
    set(HPX_PKG_LIBRARIES_BAZEL "${HPX_CONF_PREFIX}/lib/libhpx_init.a ${HPX_CONF_PREFIX}/lib/libhpx.so ${HPX_PKG_LIBRARIES}")
    set(HPX_PKG_DEBUG_LIBRARIES_BAZEL "${HPX_CONF_PREFIX}/lib/libhpx_initd.a ${HPX_CONF_PREFIX}/lib/libhpxd.so ${HPX_PKG_DEBUG_LIBRARIES}")
    set(HPX_PKG_LIBRARIES "\${libdir}/libhpx_init.a \${libdir}/libhpx.so ${HPX_PKG_LIBRARIES}")
    set(HPX_PKG_DEBUG_LIBRARIES "\${libdir}/libhpx_initd.a \${libdir}/libhpxd.so ${HPX_PKG_DEBUG_LIBRARIES}")
  endif()
endif()

if(HPX_WITH_DYNAMIC_HPX_MAIN AND (("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") OR (APPLE)))
  set(HPX_LINK_LIBRARIES "general;hpx_wrap;")
endif()

if(HPX_WITH_DYNAMIC_HPX_MAIN AND (("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") OR (APPLE)))
    set(HPX_PKG_DEBUG_LINK_LIBRARIES "\${libdir}/libhpx_wrapd.a")
    set(HPX_PKG_LINK_LIBRARIES "\${libdir}/libhpx_wrap.a")
endif()

set(HPX_LINKER_FLAGS "")
if(HPX_WITH_DYNAMIC_HPX_MAIN)
    if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
        set(HPX_LINKER_FLAGS "-Wl,-wrap=main")
    elseif(APPLE)
        set(HPX_LINKER_FLAGS "-Wl,-e,_initialize_main")
    endif()
endif()

# Get the include directories we need ...
get_directory_property(_INCLUDE_DIRS INCLUDE_DIRECTORIES)

# Add core HPX library include directory
set(_INCLUDE_DIRS ${_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR})

# replace all characters with special regex meaning
set(special_chars "^;+;*;?;$;.;-;|;(;);]")
set(binarydir_escaped ${CMAKE_BINARY_DIR})
set(sourcedir_escaped ${PROJECT_SOURCE_DIR})
foreach(special_char ${special_chars})
  string(REPLACE "${special_char}" "\\${special_char}" binarydir_escaped ${binarydir_escaped})
  string(REPLACE "${special_char}" "\\${special_char}" sourcedir_escaped ${sourcedir_escaped})
endforeach()

# '[' has special meaning in lists
string(REPLACE "[" "\\[" binarydir_escaped ${binarydir_escaped})
string(REPLACE "[" "\\[" sourcedir_escaped ${sourcedir_escaped})

foreach(dir ${_INCLUDE_DIRS})
  if((NOT dir MATCHES "^${binarydir_escaped}.*")
    AND (NOT dir MATCHES "^${sourcedir_escaped}.*"))
    set(_NEEDED_INCLUDE_DIRS "${_NEEDED_INCLUDE_DIRS} -I${dir}")
    set(_NEEDED_CMAKE_INCLUDE_DIRS ${_NEEDED_CMAKE_INCLUDE_DIRS} "${dir}")
  else()
    set(_NEEDED_BUILD_DIR_INCLUDE_DIRS "${_NEEDED_BUILD_DIR_INCLUDE_DIRS} -I${dir}")
    set(_NEEDED_CMAKE_BUILD_DIR_INCLUDE_DIRS ${_NEEDED_CMAKE_BUILD_DIR_INCLUDE_DIRS} "${dir}")
  endif()
endforeach()

set(hpx_bazel_file cmake/templates/hpx_bazel_defs.bzl.in)
if(_is_debug)
  set(hpx_bazel_file cmake/templates/hpx_bazel_defs_debug.bzl.in)
endif()

# Configure config for the install dir ...
set(HPX_CONF_INCLUDE_DIRS
  "-I${CMAKE_INSTALL_FULL_INCLUDEDIR} ${_NEEDED_INCLUDE_DIRS}"
)
set(HPX_CMAKE_CONF_INCLUDE_DIRS
  "${CMAKE_INSTALL_FULL_INCLUDEDIR}"
  "${_NEEDED_CMAKE_INCLUDE_DIRS}"
)
if("${HPX_PLATFORM_UC}" STREQUAL "XEONPHI")
  set(HPX_CONF_INCLUDE_DIRS "${HPX_CONF_INCLUDE_DIRS} -I${CMAKE_INSTALL_FULL_INCLUDEDIR}/hpx/external")
  set(HPX_CMAKE_CONF_INCLUDE_DIRS "${HPX_CMAKE_CONF_INCLUDE_DIRS} ${CMAKE_INSTALL_FULL_INCLUDEDIR}/hpx/external")
endif()
set(HPX_CONF_PREFIX ${CMAKE_INSTALL_PREFIX})
set(HPX_CONF_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
set(HPX_CONF_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")
set(HPX_CONF_LIBRARY_DIR ${HPX_LIBRARY_DIR})

configure_file(cmake/templates/${HPX_PACKAGE_NAME}Config.cmake.in
  "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HPX_PACKAGE_NAME}Config.cmake"
  ESCAPE_QUOTES @ONLY)
configure_file(cmake/templates/hpx_application.pc.in
  "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_application.pc"
  ESCAPE_QUOTES @ONLY)
configure_file(cmake/templates/hpx_application_debug.pc.in
  "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_application_debug.pc"
  ESCAPE_QUOTES @ONLY)
configure_file(cmake/templates/hpx_component.pc.in
  "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_component.pc"
  ESCAPE_QUOTES @ONLY)
configure_file(cmake/templates/hpx_component_debug.pc.in
  "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_component_debug.pc"
  ESCAPE_QUOTES @ONLY)
# Configure hpxcxx
configure_file(cmake/templates/hpxcxx.in
  "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpxcxx"
  @ONLY)

# Configure bazel file
configure_file(${hpx_bazel_file}
  "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_bazel_defs.bzl"
  ESCAPE_QUOTES @ONLY)

# ... and the build dir
set(HPX_CONF_PREFIX "${CMAKE_BINARY_DIR}")
set(HPX_CONF_LIBDIR "lib")
set(HPX_CONF_INCLUDEDIR "include")
set(HPX_CONF_INCLUDE_DIRS
  "${_NEEDED_BUILD_DIR_INCLUDE_DIRS} ${_NEEDED_INCLUDE_DIRS} -I${CMAKE_BINARY_DIR}/include"
)
foreach(lib ${HPX_LIBS})
  set(HPX_CONF_INCLUDE_DIRS
    "${HPX_CONF_INCLUDE_DIRS} -I${PROJECT_SOURCE_DIR}/libs/${lib}/include")
endforeach()
foreach(component ${HPX_COMPONENTS})
  set(HPX_CONF_INCLUDE_DIRS
    "${HPX_CONF_INCLUDE_DIRS} -I${PROJECT_SOURCE_DIR}/components/${component}/include")
endforeach()
set(HPX_CMAKE_CONF_INCLUDE_DIRS
  ${_NEEDED_CMAKE_BUILD_DIR_INCLUDE_DIRS}
  ${_NEEDED_CMAKE_INCLUDE_DIRS}
)
configure_file(cmake/templates/${HPX_PACKAGE_NAME}Config.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${HPX_PACKAGE_NAME}/${HPX_PACKAGE_NAME}Config.cmake"
  ESCAPE_QUOTES @ONLY)
configure_file(cmake/templates/hpx_application.pc.in
  "${CMAKE_CURRENT_BINARY_DIR}/lib/pkgconfig/hpx_application.pc"
  ESCAPE_QUOTES @ONLY)
configure_file(cmake/templates/hpx_application_debug.pc.in
  "${CMAKE_CURRENT_BINARY_DIR}/lib/pkgconfig/hpx_application_debug.pc"
  ESCAPE_QUOTES @ONLY)
configure_file(cmake/templates/hpx_component.pc.in
  "${CMAKE_CURRENT_BINARY_DIR}/lib/pkgconfig/hpx_component.pc"
  ESCAPE_QUOTES @ONLY)
configure_file(cmake/templates/hpx_component_debug.pc.in
  "${CMAKE_CURRENT_BINARY_DIR}/lib/pkgconfig/hpx_component_debug.pc"
  ESCAPE_QUOTES @ONLY)
# Configure hpxcxx
configure_file(cmake/templates/hpxcxx.in
  "${CMAKE_CURRENT_BINARY_DIR}/bin/hpxcxx"
  @ONLY)

# Configure bazel file
configure_file(${hpx_bazel_file}
   "${CMAKE_CURRENT_BINARY_DIR}/lib/bazel/hpx_bazel_defs.bzl"
  @ONLY)

# Configure macros for the install dir ...
set(HPX_CMAKE_MODULE_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/${HPX_PACKAGE_NAME}")
configure_file(cmake/templates/HPXMacros.cmake.in
  "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/HPXMacros.cmake"
  ESCAPE_QUOTES @ONLY)
# ... and the build dir
set(HPX_CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
configure_file(cmake/templates/HPXMacros.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${HPX_PACKAGE_NAME}/HPXMacros.cmake"
  ESCAPE_QUOTES @ONLY)

install(
  EXPORT HPXTargets
  FILE HPXTargets.cmake
#  NAMESPACE hpx::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${HPX_PACKAGE_NAME}
)

install(
  FILES
    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${HPX_PACKAGE_NAME}Config.cmake"
    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/HPXMacros.cmake"
    "${CMAKE_CURRENT_BINARY_DIR}/lib/cmake/${HPX_PACKAGE_NAME}/${HPX_PACKAGE_NAME}ConfigVersion.cmake"
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${HPX_PACKAGE_NAME}
  COMPONENT cmake
)

install(
  FILES
    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_application.pc"
    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_application_debug.pc"
    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_component.pc"
    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_component_debug.pc"
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
  COMPONENT pkgconfig
)

install(
  FILES
    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpxcxx"
  DESTINATION ${CMAKE_INSTALL_BINDIR}
  COMPONENT compiler_wrapper
  PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
  GROUP_READ GROUP_EXECUTE
  WORLD_READ WORLD_EXECUTE
)

install(
  FILES
    "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/hpx_bazel_defs.bzl"
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/bazel
  COMPONENT bazel
)
