########################################################################
# Installation stuff - create & export config files
#
if (OPENCMISS_DEPENDENCIES_ONLY)
    set(_INSTALLATION_TYPE_NAME DEPENDENCIES)
else ()
    set(_INSTALLATION_TYPE_NAME LIBRARIES)
endif ()
string(REPLACE "${ARCHITECTURE_MPI_PATH}" "" _INSTALL_BASE_PATH ${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_MPI_PREFIX})
set(OPENCMISS_CONTEXT_INSTALL_PATH "${OPENCMISS_LIBRARIES_INSTALL_NO_MPI_PREFIX}")

set(CMAKE_INSTALL_PREFIX "${_INSTALL_BASE_PATH}")

function(messaged MSG)
    #message(STATUS "OCInstall: ${MSG}")
endfunction()

###########################################################################################
# Helper functions

# Transforms a given list named VARNAME of paths.
# At first determines the relative path to RELATIVE_TO_DIR and then prefixes
# a variable named IMPORT_PREFIX_VARNAME to it, so that use of that list
# will have dynamically computed prefixes.
function(RELATIVIZE_PATH_LIST VARNAME RELATIVE_TO_DIR IMPORT_PREFIX_VARNAME)
    set(REL_LIST )
    foreach(path ${${VARNAME}})
        get_filename_component(path_abs "${path}" ABSOLUTE)
        messaged("Relativizing\n${path}\nto\n${RELATIVE_TO_DIR}")
        file(RELATIVE_PATH RELPATH "${RELATIVE_TO_DIR}" "${path_abs}")
        #getRelativePath("${path_abs}" "${RELATIVE_TO_DIR}" RELPATH)
        list(APPEND REL_LIST "\${${IMPORT_PREFIX_VARNAME}}/${RELPATH}")
    endforeach()
    set(${VARNAME} ${REL_LIST} PARENT_SCOPE)
endfunction()

function(DO_EXPORT CFILE VARS)
    message(STATUS "Exporting OpenCMISS build context: ${CFILE}")
    get_filename_component(CFILE_TYPE ${CFILE} NAME_WE)
    file(WRITE ${CFILE} "# Exported OpenCMISS configuration\n")
    file(APPEND ${CFILE} "# DO NOT EDIT THIS FILE. IT'S GENERATED BY THE OPENCMISS BUILD ENVIRONMENT\n")
    if (CFILE_TYPE STREQUAL "context")
        file(APPEND ${CFILE} "get_filename_component(_CONTEXT_OPENCMISS_IMPORT_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" DIRECTORY)\n")
        file(APPEND ${CFILE} "\n")
        file(APPEND ${CFILE} "set(CONTEXT_MPI_FILE \"\${_CONTEXT_OPENCMISS_IMPORT_PREFIX}/context-mpi-\${OPENCMISS_MPI_IMPLEMENTATION}.cmake\")\n")
        file(APPEND ${CFILE} "if (EXISTS \"\${CONTEXT_MPI_FILE}\")\n")
        file(APPEND ${CFILE} "    include(\${CONTEXT_MPI_FILE})\n")
        file(APPEND ${CFILE} "endif ()\n")
    elseif (CFILE_TYPE STREQUAL "context-dependencies")
        file(APPEND ${CFILE} "get_filename_component(_CONTEXT_DEPENDENCIES_OPENCMISS_IMPORT_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" DIRECTORY)\n")
        file(APPEND ${CFILE} "\n")
    endif ()
    file(APPEND ${CFILE} "\n")

    foreach(VARNAME ${VARS})
        if (DEFINED ${VARNAME})
            if (VARNAME MATCHES "^OPENCMISS_")
                if (CFILE_TYPE STREQUAL "context-dependencies")
                    set(_VAR_PREFIX CONTEXT_DEPENDENCIES_)
                else ()
                    set(_VAR_PREFIX CONTEXT_)
                endif ()
                string(FIND "${${VARNAME}}" " " _OUTPUT_VAR)
                if ("${_OUTPUT_VAR}" STREQUAL "-1")
                    file(APPEND ${CFILE} "set(${_VAR_PREFIX}${VARNAME} ${${VARNAME}})\n")
                else ()
                    file(APPEND ${CFILE} "set(${_VAR_PREFIX}${VARNAME} \"${${VARNAME}}\")\n")
                endif ()
            else ()
                file(APPEND ${CFILE} "set(${VARNAME} ${${VARNAME}})\n")
            endif ()
        endif ()
    endforeach()

    if (CFILE_TYPE STREQUAL "context")
        file(APPEND ${CFILE} "\n")
        file(APPEND ${CFILE} "list(APPEND CONTEXT_OPENCMISS_PREFIX_PATH_IMPORT \${CONTEXT_OPENCMISS_MPI_PREFIX_PATH_IMPORT})\n")
        file(APPEND ${CFILE} "list(REMOVE_DUPLICATES CONTEXT_OPENCMISS_PREFIX_PATH_IMPORT)\n")
        file(APPEND ${CFILE} "list(APPEND CONTEXT_OPENCMISS_LIBRARY_PATH_IMPORT \${CONTEXT_OPENCMISS_MPI_LIBRARY_PATH_IMPORT})\n")
        file(APPEND ${CFILE} "list(REMOVE_DUPLICATES CONTEXT_OPENCMISS_LIBRARY_PATH_IMPORT)\n")
        file(APPEND ${CFILE} "list(APPEND CONTEXT_OPENCMISS_BINARIES_PATH_IMPORT \${CONTEXT_OPENCMISS_MPI_BINARIES_PATH_IMPORT})\n")
        file(APPEND ${CFILE} "list(REMOVE_DUPLICATES CONTEXT_OPENCMISS_BINARIES_PATH_IMPORT)\n")
        file(APPEND ${CFILE} "\n")
        file(APPEND ${CFILE} "if (EXISTS \"${OPENCMISS_DEPENDENCIES_INSTALL_PREFIX_IMPORT}/context-dependencies.cmake\")\n")
        file(APPEND ${CFILE} "    include(${OPENCMISS_DEPENDENCIES_INSTALL_PREFIX_IMPORT}/context-dependencies.cmake)\n")
        file(APPEND ${CFILE} "endif ()\n")
    endif ()
endfunction()

###########################################################################################
# Create context.cmake in arch-path dir

# Create a copy to not destroy the original (it's being used somewhere later maybe)
set(OPENCMISS_PREFIX_PATH_IMPORT ${OPENCMISS_PREFIX_PATH_NO_MPI})
set(OPENCMISS_LIBRARY_PATH_IMPORT ${OPENCMISS_LIBRARY_PATH_NO_MPI})
set(OPENCMISS_BINARIES_PATH_IMPORT ${OPENCMISS_BINARIES_PATH_NO_MPI})

# Introduce prefixed variants of variables so we can check against them
set(OPENCMISS_CXX_COMPILER "${CMAKE_CXX_COMPILER}")
set(OPENCMISS_Fortran_COMPILER "${CMAKE_Fortran_COMPILER}")

set(EXPORT_VARS
    OPENCMISS_TOOLCHAIN
    OPENCMISS_CXX_COMPILER
    OPENCMISS_Fortran_COMPILER
    OPENCMISS_PREFIX_PATH_IMPORT
    OPENCMISS_LIBRARY_PATH_IMPORT
    OPENCMISS_BINARIES_PATH_IMPORT
    #FORTRAN_MANGLING
)

if (OPENCMISS_DEPENDENCIES_ONLY)
    set(OPENCMISS_DEPENDENCIES_CMAKE_CONFIG_PATH_IMPORT ${OPENCMISS_DEPENDENCIES_CMAKE_CONFIG_PATH})
    list(APPEND EXPORT_VARS OPENCMISS_DEPENDENCIES_CMAKE_CONFIG_PATH_IMPORT)
    relativize_path_list(OPENCMISS_DEPENDENCIES_CMAKE_CONFIG_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_DEPENDENCIES_OPENCMISS_IMPORT_PREFIX)
    list(REMOVE_DUPLICATES OPENCMISS_DEPENDENCIES_CMAKE_CONFIG_PATH_IMPORT)
    relativize_path_list(OPENCMISS_PREFIX_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_DEPENDENCIES_OPENCMISS_IMPORT_PREFIX)
    list(REMOVE_DUPLICATES OPENCMISS_PREFIX_PATH_IMPORT)
    relativize_path_list(OPENCMISS_LIBRARY_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_DEPENDENCIES_OPENCMISS_IMPORT_PREFIX)
    list(REMOVE_DUPLICATES OPENCMISS_LIBRARY_PATH_IMPORT)
    relativize_path_list(OPENCMISS_BINARIES_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_DEPENDENCIES_OPENCMISS_IMPORT_PREFIX)
    list(REMOVE_DUPLICATES OPENCMISS_BINARIES_PATH_IMPORT)
else ()
    set(OPENCMISS_DEPENDENCIES_INSTALL_PREFIX_IMPORT ${OPENCMISS_DEPENDENCIES_INSTALL_PREFIX})
    list(APPEND EXPORT_VARS OPENCMISS_DEPENDENCIES_INSTALL_PREFIX_IMPORT)
    relativize_path_list(OPENCMISS_PREFIX_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_OPENCMISS_IMPORT_PREFIX)
    list(REMOVE_DUPLICATES OPENCMISS_PREFIX_PATH_IMPORT)
    relativize_path_list(OPENCMISS_LIBRARY_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_OPENCMISS_IMPORT_PREFIX)
    list(REMOVE_DUPLICATES OPENCMISS_LIBRARY_PATH_IMPORT)
    relativize_path_list(OPENCMISS_BINARIES_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_OPENCMISS_IMPORT_PREFIX)
    list(REMOVE_DUPLICATES OPENCMISS_BINARIES_PATH_IMPORT)
    relativize_path_list(OPENCMISS_DEPENDENCIES_INSTALL_PREFIX_IMPORT "${CMAKE_INSTALL_PREFIX}${ARCHITECTURE_NO_MPI_PATH}" _CONTEXT_OPENCMISS_IMPORT_PREFIX)
    list(REMOVE_DUPLICATES OPENCMISS_DEPENDENCIES_INSTALL_PREFIX_IMPORT)
    set(OPENCMISS_CONTEXT "${CMAKE_CURRENT_BINARY_DIR}/export/context.cmake")
    do_export(${OPENCMISS_CONTEXT} "${EXPORT_VARS}")
endif ()

# Export component info
foreach(COMPONENT ${OC_REQUIRED_COMPONENTS})
    if (NOT COMPONENT STREQUAL "ZINC" OR NOT COMPONENT STREQUAL "IRON")
        list(APPEND EXPORT_VARS ${COMPONENT}_FIND_SYSTEM)
    endif ()
endforeach()
list(APPEND EXPORT_VARS BLAS_FIND_SYSTEM)
foreach(COMPONENT ${OC_BUILD_LOCAL_COMPONENTS})
    if (${COMPONENT}_VERSION AND NOT COMPONENT STREQUAL "ZINC" OR NOT COMPONENT STREQUAL "IRON")
        list(APPEND EXPORT_VARS ${COMPONENT}_VERSION)
    endif ()
endforeach()
list(APPEND EXPORT_VARS BLA_VENDOR)

if (NOT OPENCMISS_LIBRARIES_ONLY)
    set(OPENCMISS_DEPENDENCIES_CONTEXT "${CMAKE_CURRENT_BINARY_DIR}/export/context-dependencies.cmake")
    do_export(${OPENCMISS_DEPENDENCIES_CONTEXT} "${EXPORT_VARS}")
endif ()

set(OPENCMISS_MPI_PREFIX_PATH_IMPORT ${OPENCMISS_PREFIX_PATH_MPI})
set(OPENCMISS_MPI_LIBRARY_PATH_IMPORT ${OPENCMISS_LIBRARY_PATH_MPI})
set(OPENCMISS_MPI_BINARIES_PATH_IMPORT ${OPENCMISS_BINARIES_PATH_MPI})
relativize_path_list(OPENCMISS_MPI_PREFIX_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_OPENCMISS_IMPORT_PREFIX)
list(REMOVE_DUPLICATES OPENCMISS_MPI_PREFIX_PATH_IMPORT)
relativize_path_list(OPENCMISS_MPI_LIBRARY_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_OPENCMISS_IMPORT_PREFIX)
list(REMOVE_DUPLICATES OPENCMISS_MPI_LIBRARY_PATH_IMPORT)
relativize_path_list(OPENCMISS_MPI_BINARIES_PATH_IMPORT "${OPENCMISS_${_INSTALLATION_TYPE_NAME}_INSTALL_NO_MPI_PREFIX}" _CONTEXT_OPENCMISS_IMPORT_PREFIX)
list(REMOVE_DUPLICATES OPENCMISS_MPI_BINARIES_PATH_IMPORT)

set(EXPORT_MPI_VARS
    OPENCMISS_MPI_IMPLEMENTATION
    OPENCMISS_MPI_BUILD_TYPE
    OPENCMISS_MPI_HOME
    OPENCMISS_MPI_VERSION
    OPENCMISS_MPI_PREFIX_PATH_IMPORT
    OPENCMISS_MPI_LIBRARY_PATH_IMPORT
    OPENCMISS_MPI_BINARIES_PATH_IMPORT
)

if (NOT OPENCMISS_DEPENDENCIES_ONLY)
    set(OPENCMISS_MPI_CONTEXT "${CMAKE_CURRENT_BINARY_DIR}/export/context-mpi-${OPENCMISS_MPI_IMPLEMENTATION}.cmake")
    do_export(${OPENCMISS_MPI_CONTEXT} "${EXPORT_MPI_VARS}")
endif ()

# Install it
install(
    FILES ${OPENCMISS_CONTEXT} ${OPENCMISS_MPI_CONTEXT} ${OPENCMISS_DEPENDENCIES_CONTEXT}
    DESTINATION ".${ARCHITECTURE_NO_MPI_PATH}"
    COMPONENT Development
)
unset(EXPORT_VARS)

if (NOT OPENCMISS_DEPENDENCIES_ONLY)
    ###########################################################################################
    # Create opencmisslibs-config.cmake

    set(OPENCMISS_MODULE_PATH_EXPORT
        ${OPENCMISS_CMAKE_MODULE_PATH}/FindModuleWrappers
        ${OPENCMISS_CMAKE_MODULE_PATH}
        ${OPENCMISS_CMAKE_MODULE_PATH}/OpenCMISS)
    relativize_path_list(OPENCMISS_MODULE_PATH_EXPORT "${_INSTALL_BASE_PATH}" _OPENCMISS_IMPORT_PREFIX)

    if (OC_DEVELOPER AND NOT OPENCMISS_INSTALLATION_SUPPORT_EMAIL)
        message(WARNING "Dear developer! Please set the OPENCMISS_INSTALLATION_SUPPORT_EMAIL variable in OpenCMISSInstallationConfig.cmake "
                        "to your eMail address so that people using your installation can contact you for support. Thanks!")
    endif ()

    # There's litte to configure yet, but could become more
    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Templates/opencmisslibs-config.cmake
        ${CMAKE_CURRENT_BINARY_DIR}/export/opencmisslibs-config.cmake @ONLY
    )

    # Version file
    include(CMakePackageConfigHelpers)
    WRITE_BASIC_PACKAGE_VERSION_FILE(
        ${CMAKE_CURRENT_BINARY_DIR}/export/opencmisslibs-config-version.cmake
        COMPATIBILITY AnyNewerVersion
    )
    install(
        FILES ${CMAKE_CURRENT_BINARY_DIR}/export/opencmisslibs-config.cmake
            ${CMAKE_CURRENT_BINARY_DIR}/export/opencmisslibs-config-version.cmake
        DESTINATION "."
        COMPONENT Development
    )

    # Install mingw libraries if we built with mingw
    # Needs checking - maybe the bundle stuff in iron (for windows) can do this automatically.
    if (MINGW AND WIN32)
        get_filename_component(COMPILER_BIN_DIR ${CMAKE_C_COMPILER} PATH)
        file(GLOB MINGW_DLLS "${COMPILER_BIN_DIR}/*.dll")
        install(FILES ${MINGW_DLLS}
            DESTINATION ${ARCHITECTURE_MPI_PATH}/bin
            COMPONENT Runtime)
    endif ()
endif ()
