cmake_minimum_required(VERSION 3.0)
PROJECT(Spintrum)

if(NOT WIN32)
    string(ASCII 27 Esc)
    set(ColourReset "${Esc}[m")
    set(ColourBold  "${Esc}[1m")
    set(Red         "${Esc}[31m")
    set(Green       "${Esc}[32m")
    set(Yellow      "${Esc}[33m")
    set(Blue        "${Esc}[34m")
    set(Magenta     "${Esc}[35m")
    set(Cyan        "${Esc}[36m")
    set(White       "${Esc}[37m")
    set(BoldRed     "${Esc}[1;31m")
    set(BoldGreen   "${Esc}[1;32m")
    set(BoldYellow  "${Esc}[1;33m")
    set(BoldBlue    "${Esc}[1;34m")
    set(BoldMagenta "${Esc}[1;35m")
    set(BoldCyan    "${Esc}[1;36m")
    set(BoldWhite   "${Esc}[1;37m")
endif()

#This allows in-source build in case it's a pip installation.
#This is OK because the directory is temporary and will be removed eventually
if(NOT DEFINED PythonInstallation)
    if(EXISTS "setup.py")
        message(FATAL_ERROR "${BoldRed}Error: You cannot make an in-source build. Please create a sub-dir and cmake in it.${ColourReset}")
    endif()
endif()

#Get rid of warning about unused variable
set(PythonInstallation "OFF")


if(NOT DEFINED SpintrumPath)
    set(SpintrumPath src/)
endif()
if(NOT DEFINED PolymathPath)
    set(PolymathPath 3rdparty/Polymath/)
endif()
if(NOT DEFINED OpenBLASPath)
    set(OpenBLASPath spintrum/OpenBLAS_install/)
endif()
if(NOT DEFINED OptimizationLevel)
    set(OptimizationLevel -Ofast)
endif()
set(CMAKE_BUILD_TYPE Release)
#add_definitions(-DPOLYMATH_DEBUG)


set(VERSION 0.1.6)
execute_process(COMMAND "python3 -c 'from spintrum import meta; print(meta.__version__)'" OUTPUT_VARIABLE VERSION)
add_definitions(-DSPINTRUM_VERSION="${VERSION}")

INCLUDE_DIRECTORIES(${PolymathPath}/include)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${SpintrumPath})
INCLUDE_DIRECTORIES(${OpenBLASPath})

file(GLOB_RECURSE PolymathSrc
    "${PolymathPath}/src/*.cpp"
    )

file(GLOB_RECURSE includesList
    "${PolymathPath}/include/*.h"
    "${SpintrumPath}/common/*.h"
    )

OPTION(BUILD_SHARED_LIBS "turn OFF for .a libs" ON)

SET(SpintrumMain src/Spintrum.cpp)

ADD_LIBRARY(spintrum SHARED
    ${SpintrumMain}
    ${PolymathSrc}
    ${includesList}
    )

if (UNIX)
    IF(CMAKE_BUILD_TYPE MATCHES Release)
        message("${Blue}Building in Release mode${ColourReset}")
        message("${Green}Target optimization level: ${OptimizationLevel}${ColourReset}")
        SET( CMAKE_CXX_FLAGS_RELEASE "${OptimizationLevel}")
        SET( CMAKE_C_FLAGS_RELEASE "${OptimizationLevel}")
    ELSE()
        message("${BoldRed}Building in Debug mode${ColourReset}")
        SET( CMAKE_CXX_FLAGS_RELEASE "-g")
        SET( CMAKE_C_FLAGS_RELEASE "-g")
    ENDIF(CMAKE_BUILD_TYPE MATCHES Release)

    function(FindOpenBLAS path found)
        if(EXISTS "${path}/lib/libopenblas.so" OR EXISTS "${path}/lib/libopenblas.so.0")
            set(${found} "ON" PARENT_SCOPE)
        else()
            set(${found} "OFF" PARENT_SCOPE)
        endif()
    endfunction()

    #find OpenBLAS
    set(OpenBLASTestPath ${OpenBLASPath})
    set(foundOpenBLAS "OFF")
    FindOpenBLAS("${OpenBLASTestPath}" "foundOpenBLAS")
    if(NOT ${foundOpenBLAS})
        set(OpenBLASTestPath "../${OpenBLASTestPath}")
        FindOpenBLAS("${OpenBLASTestPath}" "foundOpenBLAS")
    endif()

    if(${foundOpenBLAS})
        message("${BoldGreen}I found a compiled version of OpenBLAS in ${OpenBLASPath}. Everything looks great!${ColourReset}")
        TARGET_LINK_LIBRARIES(spintrum -L"${OpenBLASPath}/lib")
        TARGET_LINK_LIBRARIES(spintrum -L"../${OpenBLASPath}/lib")
    else()
        message("${BoldRed}WARNING: OpenBLAS shared library was not found in ${OpenBLASPath}. This may lead to a failure in compilation, unless OpenBLAS is present in the operating system.${ColourReset}")
        message("${BoldGreen}I will try to fix this problem by considering that your system may have OpenBLAS installed.${ColourReset}")
        add_definitions(-DOPENBLAS_FROM_SYSTEM)
    endif()

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -shared -pedantic-errors")
    file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/spintrum/lib/)
    SET(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/spintrum/lib/) #output libspintrum.so to this directory
    TARGET_LINK_LIBRARIES(spintrum libopenblas.so)
    TARGET_LINK_LIBRARIES(spintrum)
endif (UNIX)

if (MSVC)
    include (GenerateExportHeader)
    set(openblasdir D:/libs/OpenBLAS-0.2.19)
    set(openblasbuilddir D:/libs/OpenBLAS-0.2.19-build-32/)
    add_definitions(-DISWIN32)
    TARGET_LINK_LIBRARIES(spintrum -lopenblas)
    TARGET_LINK_LIBRARIES(spintrum D:/libs/OpenBLAS-0.2.19-build-32/lib/libopenblas.lib)
    TARGET_LINK_LIBRARIES(spintrum)
    INCLUDE_DIRECTORIES(include ${openblasdir})
    GENERATE_EXPORT_HEADER(m
        BASE_NAME m
        EXPORT_MACRO_NAME M_EXPORTS
        EXPORT_FILE_NAME m_exports.h
        STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC)
endif(MSVC)
