# -------------------------------------------------------------------------------------------------------#
# UKRmol+ suite - outer region                                                                           #
# -------------------------------------------------------------------------------------------------------#
#                                                                                                        #
# Environment variables                                                                                  #
# ---------------------                                                                                  #
#                                                                                                        #
# - BLA_VENDOR              Defines the BLAS/LAPACK vendor, typically "Intel10_64ilp" for ILP64 MKL.     #
#                           In case of Intel Compiler this needs to be supplemented with the option      #
#                           "-mkl". (Only available with CMake 3.13+)                                    #
#                                                                                                        #
# - BLA_STATIC              Look for static BLAS/LAPACK libraries. In case of Intel Compiler, this needs #
#                           to be consistent with usage or absence of the flag "-static-intel".          #
#                           (Only available with CMake 3.13+)                                            #
#                                                                                                        #
# CMake options                                                                                          #
# -------------                                                                                          #
#                                                                                                        #
# - GBTOLIB_INCLUDE_DIRS    GBTOlib Fortran mod file directory.                                          #
#                                                                                                        #
# - GBTOLIB_LIBRARIES       GBTOlib library to link with.                                                #
#                                                                                                        #
# - BLA_F95                 Use external blas95/lapack95 wrappers from Intel MKL (default: OFF).         #
#                                                                                                        #
# - BUILD_DOC               Generate development documentation (default: ON).                            #
#                                                                                                        #
# - WITH_GIT                Attempt to retrieve code version from the local Git repository clone         #
#                           (default: ON).                                                               #
#                                                                                                        #
# -------------------------------------------------------------------------------------------------------#

cmake_minimum_required(VERSION 3.5...3.31)

project(UKRmol+ C Fortran)

include(GNUInstallDirs)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

list(APPEND CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

set(CMAKE_Fortran_MODULE_DIRECTORY "mod")

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif(NOT CMAKE_BUILD_TYPE)

# -------------------------------------------------------------------------------------------------------#
# User switches

option(BUILD_DOC "Generate automatic documentation (requires Doxygen & Graphviz)" ON)
option(WITH_GIT "Add Git revision to program header (requires Git)" ON)
option(WITH_GSL "Use GNU Scientific Library instead of some in-house codes (requires GSL)" OFF)

# -------------------------------------------------------------------------------------------------------#
# Set up Doxygen documentation

if(BUILD_DOC)
    find_package(Doxygen)
    if(NOT DOXYGEN_FOUND)
        message(STATUS "Doxygen needs to be installed to generate the doxygen documentation")
    endif(NOT DOXYGEN_FOUND)
endif(BUILD_DOC)

# ------------------------------------------------------------------------------------------------
# Libraries

find_package(OpenMP REQUIRED)

# find BLAS + LAPACK
if(NOT "$ENV{BLA_STATIC}" STREQUAL "")
    set(BLA_STATIC ON)
endif()
find_package(LAPACK REQUIRED)

# ------------------------------------------------------------------------------------------------
# Collect infomation about version of the code if possible

if (WITH_GIT)
    find_package(Git)
    if (Git_FOUND)
        execute_process(
            COMMAND "${GIT_EXECUTABLE}" log -1 --pretty=format:"%an"
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
            OUTPUT_VARIABLE UKRMOL_OUT_GIT_AUTH
            OUTPUT_STRIP_TRAILING_WHITESPACE
            ERROR_QUIET
        )
        execute_process(
            COMMAND "${GIT_EXECUTABLE}" log -1 --pretty=format:"%h"
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
            OUTPUT_VARIABLE UKRMOL_OUT_GIT_HASH
            OUTPUT_STRIP_TRAILING_WHITESPACE
            ERROR_QUIET
        )
        execute_process(
            COMMAND "${GIT_EXECUTABLE}" log -1 --pretty=format:"%ad"
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
            OUTPUT_VARIABLE UKRMOL_OUT_GIT_DATE
            OUTPUT_STRIP_TRAILING_WHITESPACE
            ERROR_QUIET
        )
        execute_process(
            COMMAND "${GIT_EXECUTABLE}" describe --tags HEAD
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
            OUTPUT_VARIABLE UKRMOL_OUT_GIT_TAGS
            OUTPUT_STRIP_TRAILING_WHITESPACE
            ERROR_QUIET
        )
    endif (Git_FOUND)
endif (WITH_GIT)

# override the data from the .release tag file if present
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.release)
    file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/.release RELEASE_INFO)
    if(RELEASE_INFO)
        list(GET RELEASE_INFO 0 UKRMOL_OUT_GIT_HASH)
        list(GET RELEASE_INFO 1 UKRMOL_OUT_GIT_AUTH)
        list(GET RELEASE_INFO 2 UKRMOL_OUT_GIT_DATE)
    endif()
endif()

# communicate the version to the user
message(STATUS "Last UKRmol-out commit author: ${UKRMOL_OUT_GIT_AUTH}")
message(STATUS "Last UKRmol-out commit hash: ${UKRMOL_OUT_GIT_HASH}")
message(STATUS "Last UKRmol-out commit date: ${UKRMOL_OUT_GIT_DATE}")

# ------------------------------------------------------------------------------------------------
# Compiler compatibility (GCC 8.x has no findloc!)

include(CheckFortranSourceCompiles)

check_fortran_source_compiles("      program p\n      a = findloc([1],1,1)\n      end program" have_findloc)

if(NOT have_findloc)
    add_definitions(-DHAVE_NO_FINDLOC)
endif()

# ------------------------------------------------------------------------------------------------
# Build targets

add_subdirectory(source/libutil)
add_subdirectory(source/libouter)
add_subdirectory(source/compak)
add_subdirectory(source/dipelm)
add_subdirectory(source/multidip)
add_subdirectory(source/programs)

if(BUILD_TESTING)
    enable_testing()
    add_subdirectory(tests/suite)
endif()

file(GLOB outer_docs "${PROJECT_SOURCE_DIR}/doc/*")
install(FILES ${outer_docs} DESTINATION "${CMAKE_INSTALL_DOCDIR}")

# -------------------------------------------------------------------------------------------------------#
# Define distribution release target (make dist)

file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/.release-out
    CONTENT "\"${UKRMOL_OUT_GIT_TAGS}\"\n${UKRMOL_OUT_GIT_AUTH}\n${UKRMOL_OUT_GIT_DATE}\n"
)

add_custom_command(OUTPUT ukrmol-out.tar
    COMMAND git archive --format tar --prefix=ukrmol-out-${UKRMOL_OUT_GIT_TAGS}/ -o ${CMAKE_BINARY_DIR}/ukrmol-out.tar HEAD
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(dist-out
    DEPENDS ukrmol-out.tar ${CMAKE_BINARY_DIR}/.release-out
    COMMAND tar --extract --file ukrmol-out.tar
    COMMAND cp .release-out ukrmol-out-${UKRMOL_OUT_GIT_TAGS}/.release
    COMMAND tar --create --gzip --file ukrmol-out-${UKRMOL_OUT_GIT_TAGS}.tar.gz ukrmol-out-${UKRMOL_OUT_GIT_TAGS}
    COMMAND rm -rf ukrmol-out-${UKRMOL_OUT_GIT_TAGS}
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)

if(NOT TARGET dist)
    add_custom_target(dist)  # may be already defined elsewhere when building jointly with UKRmol-in
endif()

add_dependencies(dist dist-out)
