# Copyright (C) 2019-2021  CZ.NIC, z. s. p. o.
#
# This file is part of FRED.
#
# FRED is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FRED is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with FRED.  If not, see <https://www.gnu.org/licenses/>.

cmake_minimum_required(VERSION 3.5)

# Set CMake policies to support later version behaviour
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) # option() honors variables already set

# build options

option(LIBLOG_BUILD_TESTS "Build liblog tests" OFF)
set(SPDLOG_ACTIVE_LEVEL "SPDLOG_LEVEL_TRACE" CACHE STRING "Enable/disable log calls at compile time according to global level.")
option(FMT_STRING_ALIAS "Enable compile-time format string checks." ON)
option(FMT_HEADER_ONLY "Use fmt library in header-only manner." OFF) # significantly reduce build time
option(CMAKE_EXPORT_COMPILE_COMMANDS "Enable output of compile commands during generation." ON)

# compile options

find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
endif()

# project details

include("cmake/package.cmake")

package(liblog
    FULL_VERSION "1.4.2")

project(LibLog
    VERSION ${PACKAGE_VERSION}
    LANGUAGES CXX)

# package dependencies

include("cmake/package_dependencies.cmake")
add_package_dependencies(FROM_FILE "dependencies.txt")
# this dependency is third party, so it will not create dist_spdlog target, we have to create and provide it here
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" spdlog_dst_relative_dir "${SPDLOG_DIR}")
provide_package_dependency_dist(spdlog SRC_DIR "${SPDLOG_DIR}" DST_RELATIVE_DIR "${spdlog_dst_relative_dir}")

# configuration files

configure_file(log.pc.in log.pc @ONLY)

# build

add_library(log
    STATIC
    src/liblog/context.cc
    src/liblog/impl/to_spdlog_level.cc
    src/liblog/impl/to_spdlog_pattern_time_type.cc
    src/liblog/log.cc
    src/liblog/log_config.cc
    src/liblog/sink/console_sink_config.cc
    src/liblog/sink/file_sink_config.cc
    src/liblog/sink/impl/console_sink.cc
    src/liblog/sink/impl/file_sink.cc
    src/liblog/sink/impl/syslog_sink.cc
    src/liblog/sink/syslog_sink_config.cc
    src/liblog/thread_number.cc)

add_library(LibLog::library ALIAS log)

set_target_properties(log PROPERTIES
    VERSION ${PROJECT_VERSION}
    CXX_STANDARD 14
    CXX_STANDARD_REQUIRED YES
    CXX_EXTENSIONS NO
    ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib"
    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib"
    OUTPUT_NAME "log")

target_compile_definitions(log PUBLIC SPDLOG_ACTIVE_LEVEL=${SPDLOG_ACTIVE_LEVEL})
if(FMT_STRING_ALIAS)
    target_compile_definitions(log PUBLIC FMT_STRING_ALIAS)
endif()

target_compile_options(log
    PRIVATE
        $<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -ggdb -grecord-gcc-switches>)

find_package(Threads REQUIRED)
find_package(Boost 1.53.0
    COMPONENTS
        system
        thread
        serialization
        filesystem
    REQUIRED)
find_package(PkgConfig REQUIRED)

target_include_directories(log
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR})

target_link_libraries(log PUBLIC
    Threads::Threads
    Boost::system
    Boost::thread)

if(FMT_HEADER_ONLY)
    target_compile_definitions(log PUBLIC FMT_HEADER_ONLY)
    target_link_libraries(log PUBLIC spdlog::spdlog_header_only)
else()
    target_link_libraries(log PUBLIC spdlog::spdlog)
endif()

if(LIBLOG_BUILD_TESTS)

add_subdirectory(test/liblog)

endif()

# install

include(GNUInstallDirs)

install(TARGETS log
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/log.pc DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)

# uninstall

get_directory_property(HAS_PARENT "PARENT_DIRECTORY")
if(NOT HAS_PARENT)
    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)
endif()

# dist

include("cmake/package_dist.cmake")

package_dist(PACKAGE_NAME "${PROJECT_NAME}"
             PACKAGE_PREFIX "${LIBLOG_PREFIX}"
             PACKAGE_TARNAME "${PACKAGE_TARNAME}")
