cmake_minimum_required(VERSION 3.5)

project(libpg VERSION 0.9.3 LANGUAGES CXX)

##############################################
# Declare dependencies
set(PostgreSQL_ADDITIONAL_VERSIONS "9.6")
find_package(PostgreSQL ${PostgreSQL_ADDITIONAL_VERSIONS} REQUIRED)
find_package(Boost 1.53.0
    COMPONENTS
        system
        date_time
    REQUIRED)
find_package(PkgConfig REQUIRED)

##############################################
# Create target and set properties
add_library(pg STATIC
    src/extendable_query_arguments.cc
    src/libpq_layer.cc
    src/pg_connection.cc
    src/pg_result.cc
    src/pg_ro_transaction.cc
    src/pg_rw_transaction.cc
    src/pg_transaction.cc
    src/prepared_transaction.cc
    src/psql_type.cc
    src/query.cc
    src/query_parameter.cc
    src/time_zone.cc
    src/detail/libpq_layer_interface.cc
    src/detail/libpq_layer_impl.cc
    src/detail/unwrapper.cc
    src/detail/wrapper.cc
    src/sql_state/show_code.cc
    src/util/strong_type.cc)

#Add an alias so that library can be used inside the build tree, e.g. when testing
add_library(LibPg::library ALIAS pg)

#Set target properties
target_include_directories(pg
    PUBLIC
        $<INSTALL_INTERFACE:include>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        ${PostgreSQL_INCLUDE_DIRS}
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}
)

target_compile_features(pg PRIVATE cxx_decltype_auto)
target_compile_options(pg PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -ggdb -grecord-gcc-switches>)
set_target_properties(pg PROPERTIES
    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib"
    ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")

target_link_libraries(pg
    PUBLIC
        Boost::system
        Boost::date_time
    PRIVATE
        ${PostgreSQL_LIBRARIES}
)

add_subdirectory(test)

get_directory_property(has_parent PARENT_DIRECTORY)
if("${has_parent}" STREQUAL "")
    ##############################################
    # Installation instructions
    include(GNUInstallDirs)

    install(TARGETS pg
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    )
    add_custom_target(uninstall
        COMMAND xargs -L10 rm -v < ${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt
        COMMAND cat ${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt | xargs -L1 dirname | sort | uniq | xargs -L10 rmdir -p --ignore-fail-on-non-empty)

    find_program(GIT_PROGRAM git)
    if(NOT VERSION)
        if(NOT GIT_PROGRAM)
            message(FATAL_ERROR "git not found; you need to pass -DVERSION=")
        endif()
        if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
            message(FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}/ not a git repository")
        endif()
        execute_process(COMMAND ${GIT_PROGRAM} "describe" "--tags"
                        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                        OUTPUT_VARIABLE RAWVERSION)
        string(REGEX REPLACE "(-.*)?\n" "" VERSION "${RAWVERSION}")
    endif()
    set(TARBALL_FILE_NAME "${PROJECT_NAME}-${VERSION}")

    configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)

    if(EXISTS ${CMAKE_SOURCE_DIR}/.git AND GIT_PROGRAM)
        if(NOT TARGET dist)
            add_custom_command(OUTPUT ${TARBALL_FILE_NAME}.tar.gz
                COMMAND ${GIT_PROGRAM} archive --format=tar.gz --prefix=${TARBALL_FILE_NAME}/ HEAD -o ${CMAKE_CURRENT_BINARY_DIR}/${TARBALL_FILE_NAME}.tar.gz
                WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                COMMENT "Create tarball ${TARBALL_FILE_NAME}.tar.gz")
            add_custom_target(dist DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARBALL_FILE_NAME}.tar.gz)
        endif()

        if(NOT TARGET distcheck)
            set(DISTCHECK_BUILD_DIR "_build")
            set(DISTCHECK_INSTALL_DIR "_inst")
            if(${CMAKE_GENERATOR} STREQUAL "Ninja")
                set(DISTCHECK_BUILD_CMD "ninja")
                set(DISTCHECK_MAKEFLAGS "")
            else()
                set(DISTCHECK_BUILD_CMD "make")
                execute_process(COMMAND "grep" "-c" "model name" "/proc/cpuinfo"
                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
                    OUTPUT_VARIABLE NOCPUS)
                string(REGEX REPLACE "\n" "" NOCPUS ${NOCPUS})
                set(DISTCHECK_MAKEFLAGS "MAKEFLAGS=-j${NOCPUS}")
            endif()
            add_custom_target(clean_before_distcheck
                COMMAND rm -rf ${DISTCHECK_BUILD_DIR} ${DISTCHECK_INSTALL_DIR} ${TARBALL_FILE_NAME}
                COMMENT "cleaning before distcheck start")
            add_custom_target(distcheck_make_dirs
                COMMAND mkdir ${DISTCHECK_BUILD_DIR} ${DISTCHECK_INSTALL_DIR}
                COMMENT "make distcheck build and install directories"
                DEPENDS clean_before_distcheck)
            add_custom_target(distcheck_unpack_archive
                COMMAND tar xzf ${TARBALL_FILE_NAME}.tar.gz
                COMMENT "Checking the distribution archive..."
                DEPENDS dist distcheck_make_dirs)
            add_custom_target(distcheck_configure
                COMMAND ${CMAKE_COMMAND} -G${CMAKE_GENERATOR} -DVERSION=${VERSION} -DCMAKE_INSTALL_PREFIX=../${DISTCHECK_INSTALL_DIR} ../${TARBALL_FILE_NAME}
                COMMENT "configure distcheck"
                DEPENDS distcheck_unpack_archive
                WORKING_DIRECTORY ${DISTCHECK_BUILD_DIR})
            add_custom_target(distcheck_make
                COMMAND ${DISTCHECK_MAKEFLAGS} ${DISTCHECK_BUILD_CMD}
                COMMENT "make"
                DEPENDS distcheck_configure
                WORKING_DIRECTORY ${DISTCHECK_BUILD_DIR})
            add_custom_target(distcheck_install
                COMMAND ${DISTCHECK_BUILD_CMD} install
                COMMENT "make install"
                DEPENDS distcheck_make
                WORKING_DIRECTORY ${DISTCHECK_BUILD_DIR})
            add_custom_target(distcheck_uninstall
                COMMAND ${DISTCHECK_BUILD_CMD} uninstall
                COMMENT "make uninstall"
                DEPENDS distcheck_install
                WORKING_DIRECTORY ${DISTCHECK_BUILD_DIR})
            add_custom_target(distcheck_clean
                COMMAND ${DISTCHECK_BUILD_CMD} clean
                COMMENT "make clean"
                DEPENDS distcheck_uninstall
                WORKING_DIRECTORY ${DISTCHECK_BUILD_DIR})
            add_custom_target(distcheck
                COMMAND rm -rf ${DISTCHECK_BUILD_DIR} ${DISTCHECK_INSTALL_DIR} ${TARBALL_FILE_NAME}
                COMMENT "PASS: '${TARBALL_FILE_NAME}.tar.gz' is ready for distribution."
                DEPENDS distcheck_clean)
        endif()
    else()
        message(STATUS "no git -- not including dist and distcheck targets")
    endif()
endif()
