cmake_minimum_required(VERSION 3.5)

file(READ "libclingcon/clingcon.h" main)
string(REGEX MATCH "#define CLINGCON_VERSION \"([^\"]*)\"" clingov ${main})

project(CLINGCON VERSION "${CMAKE_MATCH_1}" LANGUAGES C CXX)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
    message(STATUS "No build type selected - using 'Release'")
    set(CMAKE_BUILD_TYPE "Release")
endif()

# Enable folders in IDEs like Visual Studio
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)

include(GNUInstallDirs)
include(CMakeDependentOption)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

option(CLINGCON_MANAGE_RPATH "set rpath if not installed into system directory" ON)
option(CLINGCON_BUILD_TESTS "build tests" OFF)
option(CLINGCON_BUILD_SHARED "build clingcon library shared" ON)
option(CLINGCON_USE_LOCAL_CATCH
"Advanced option to build against bundled or installed catch."
ON)
option(CLINGCON_PROFILE "profile clingcon" OFF)

set(PYCLINGCON_ENABLE "auto" CACHE STRING "build with python support: OFF, auto, require, pip
auto: enable python support if python is available
require: enable python support and fails if python is not available
pip: enable python support and link against the clingo python module")
set(PYCLINGCON_INSTALL "prefix" CACHE STRING "configure where to install python module: user, system, prefix
user: install into user prefix
system: install into python library
prefix: install into install prefix")
set(PYCLINGCON_PIP_PATH "" CACHE STRING "path to clingo pip package")
set(PYCLINGCON_SUFFIX "" CACHE STRING "suffix for python module")
set(PYCLINGCON_INSTALL_DIR "" CACHE STRING "path where to install python module")

mark_as_advanced(CLINGCON_BUILD_SHARED)
mark_as_advanced(PYCLINGCON_PIP_PATH)
mark_as_advanced(PYCLINGCON_SUFFIX)
mark_as_advanced(PYCLINGCON_INSTALL_DIR)

if (MSVC)
    set(VC_RELEASE_LINK_OPTIONS /LTCG)
    SET(CMAKE_EXE_LINKER_FLAGS_RELEASE    "${CMAKE_EXE_LINKER_FLAGS_RELEASE}    ${VC_RELEASE_LINK_OPTIONS}")
    SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${VC_RELEASE_LINK_OPTIONS}")
    SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${VC_RELEASE_LINK_OPTIONS}")
    SET(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} ${VC_RELEASE_LINK_OPTIONS}")
    add_compile_options("/wd4244" "/wd4267" "/wd26451")
    add_definitions("-D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS")
endif()

if (CLINGCON_BUILD_SHARED)
    set(CMAKE_CXX_VISIBILITY_PRESET hidden)
    set(CMAKE_C_VISIBILITY_PRESET hidden)
endif()

enable_testing()

if (CLINGCON_MANAGE_RPATH)
    set(CMAKE_SKIP_BUILD_RPATH FALSE)
    set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
    set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
    list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_FULL_LIBDIR}" isSystemDir)
    if ("${isSystemDir}" STREQUAL "-1")
        set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")
    endif()
endif()

if (NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
endif()
if (NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
endif()
if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
endif()
if (NOT CMAKE_IMPORT_LIBRARY_PREFIX)
    set(CMAKE_IMPORT_LIBRARY_PREFIX import_)
endif()

add_subdirectory(third_party)

if (PYCLINGCON_ENABLE)
    if(NOT PYCLINGCON_ENABLE STREQUAL "pip" AND (CMAKE_VERSION VERSION_GREATER "3.15.0" OR CMAKE_VERSION VERSION_EQUAL "3.15.0"))
        if(DEFINED PYTHON_EXECUTABLE AND NOT DEFINED Python_EXECUTABLE)
            set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
        endif()
        if(DEFINED PYTHON_INCLUDE_DIR AND NOT DEFINED Python_INCLUDE_DIR)
            set(Python_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
        endif()
        if(DEFINED PYTHON_LIBRARY AND NOT DEFINED Python_LIBRARY)
            set(Python_LIBRARY "${PYTHON_LIBRARY}")
        endif()
        if (POLICY CMP0094)
            cmake_policy(SET CMP0094 NEW)
        endif()
        set(_args Interpreter)
        set(_args ${_args} Development)
        if (PYCLINGCON_ENABLE STREQUAL "require" OR PYCLINGCON_ENABLE STREQUAL "pip")
            set(_args ${_args} REQUIRED)
        endif()
        find_package(Python COMPONENTS ${_args})
    else()
        set(_args)
        if (PYCLINGCON_ENABLE STREQUAL "require" OR PYCLINGCON_ENABLE STREQUAL "pip")
            set(_args ${_args} REQUIRED)
        endif()
        if (PYCLINGCON_ENABLE STREQUAL "pip")
            find_package(PythonExtensions ${_args})
        else()
            find_package(PythonInterp ${_args})
            find_package(PythonLibs ${_args})
        endif()
        set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
        set(Python_VERSION_MAJOR "${PYTHON_VERSION_MAJOR}")
        if (PYTHONLIBS_FOUND)
            add_library(Python::Python INTERFACE IMPORTED)
            add_library(Python::Module INTERFACE IMPORTED)
            set(Python_Development_FOUND ON)
            set(Python_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}")
            set(Python_VERSION "${PYTHONLIBS_VERSION_STRING}")
            set_property(TARGET Python::Python PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${PYTHON_INCLUDE_DIRS}")
            set_property(TARGET Python::Module PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${PYTHON_INCLUDE_DIRS}")
            set_property(TARGET Python::Python PROPERTY INTERFACE_LINK_LIBRARIES "${PYTHON_LIBRARIES}")
            if (MSVC) 
                set_property(TARGET Python::Module PROPERTY INTERFACE_LINK_LIBRARIES "${PYTHON_LIBRARIES}")
            endif()
        endif()
    endif()
endif()

if (PYCLINGCON_ENABLE STREQUAL "pip")
    if (NOT CLINGCON_BUILD_SHARED)
        message(FATAL_ERROR "building against the pip package requires CLINGCON_BUILD_SHARED.")
    endif()
    add_library(libclingo INTERFACE)
    if (NOT PYCLINGCON_PIP_PATH)
        execute_process(COMMAND ${Python_EXECUTABLE} ${CLINGCON_SOURCE_DIR}/cmake/python-site.py clingo OUTPUT_VARIABLE PYCLINGCON_PIP_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
    endif()
    file(TO_CMAKE_PATH "${PYCLINGCON_PIP_PATH}" _PYCLINGCON_PIP_PATH)
    target_include_directories(libclingo INTERFACE "${_PYCLINGCON_PIP_PATH}")
    if (WIN32)
        target_link_libraries(libclingo INTERFACE "${_PYCLINGCON_PIP_PATH}/import__clingo.lib")
    elseif (APPLE)
        target_link_options(libclingo INTERFACE "-undefined" "dynamic_lookup")
    endif()
    add_subdirectory(libclingcon)
    add_subdirectory(libpyclingcon)
else()
    find_package(Clingo REQUIRED)
    add_subdirectory(libclingcon)
    if (PYCLINGCON_ENABLE AND Python_Development_FOUND)
        add_subdirectory(libpyclingcon)
    endif()
    add_subdirectory(app)
endif()
