# Copyright (C) 2009-2021 Greenbone AG#
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.


# Needed for 'pkg_check_modules' function
include (FindPkgConfig)

if (NOT PKG_CONFIG_FOUND)
  message(FATAL_ERROR "pkg-config executable not found. Aborting.")
endif (NOT PKG_CONFIG_FOUND)

## Check for existence of required libraries
pkg_check_modules (LIBMICROHTTPD REQUIRED libmicrohttpd>=0.9.0)
pkg_check_modules (LIBXML REQUIRED libxml-2.0)
pkg_check_modules (GLIB REQUIRED glib-2.0>=2.42)
pkg_check_modules (LIBGVM_BASE REQUIRED libgvm_base>=22.8)
pkg_check_modules (LIBGVM_UTIL REQUIRED libgvm_util>=22.8)
pkg_check_modules (LIBGVM_GMP REQUIRED libgvm_gmp>=22.8)
pkg_check_modules (GNUTLS REQUIRED gnutls>=3.2.15)
pkg_check_modules (ZLIB REQUIRED zlib>=1.2)
pkg_check_modules (BROTLI libbrotlienc)

message (STATUS "Looking for libgcrypt...")
find_library (LIBGCRYPT gcrypt)
if (NOT LIBGCRYPT)
  message (SEND_ERROR "The libgcrypt library is required.")
else (NOT LIBGCRYPT)
  message (STATUS "Looking for libgcrypt... ${LIBGCRYPT}")
  execute_process (COMMAND libgcrypt-config --libs
    OUTPUT_VARIABLE LIBGCRYPT_LDFLAGS
    OUTPUT_STRIP_TRAILING_WHITESPACE)
  execute_process (COMMAND libgcrypt-config --cflags
    OUTPUT_VARIABLE LIBGCRYPT_CFLAGS
    OUTPUT_STRIP_TRAILING_WHITESPACE)
endif (NOT LIBGCRYPT)

if (NOT LIBMICROHTTPD_FOUND OR NOT LIBXML_FOUND OR NOT GLIB_FOUND OR
    (GTHREAD_REQUIRED AND NOT GTHREAD_FOUND) OR NOT
    LIBGVM_GMP_FOUND OR NOT GNUTLS_FOUND OR NOT
    LIBGCRYPT OR NOT ZLIB_FOUND)
  message (FATAL_ERROR "One or more required libraries was not found "
    "(see message above), please install the missing "
    "libraries and run cmake again.")
endif (NOT LIBMICROHTTPD_FOUND OR NOT LIBXML_FOUND OR NOT GLIB_FOUND OR
  (GTHREAD_REQUIRED AND NOT GTHREAD_FOUND) OR NOT
  LIBGVM_GMP_FOUND OR NOT GNUTLS_FOUND OR NOT LIBGCRYPT OR NOT ZLIB_FOUND)

## Program

set (HARDENING_FLAGS            "-D_FORTIFY_SOURCE=2 -fstack-protector")
set (LINKER_HARDENING_FLAGS     "-Wl,-z,relro -Wl,-z,now")

set (CMAKE_C_FLAGS              "${CMAKE_C_FLAGS} -Wall -Wformat -Wformat-security ${COVERAGE_FLAGS}")
if (BROTLI_FOUND)
  set (CMAKE_C_FLAGS            "${CMAKE_C_FLAGS} -DHAVE_BROTLI=1")
endif (BROTLI_FOUND)

set (CMAKE_C_FLAGS_DEBUG        "${CMAKE_C_FLAGS_DEBUG} -Werror")
set (CMAKE_C_FLAGS_RELEASE      "${CMAKE_C_FLAGS_RELEASE} ${HARDENING_FLAGS}")

include_directories (${LIBMICROHTTPD_INCLUDE_DIRS} ${LIBXML_INCLUDE_DIRS}
                     ${GLIB_INCLUDE_DIRS}
                     ${LIBGVM_BASE_INCLUDE_DIRS}
                     ${LIBGVM_UTIL_INCLUDE_DIRS}
                     ${LIBGVM_GMP_INCLUDE_DIRS}
                     ${GNUTLS_INCLUDE_DIRS}
                     ${ZLIB_INCLUDE_DIRS}
                     ${BROTLI_INCLUDE_DIRS})

find_package (Threads)

## Program

add_executable (gsad
                gsad.c
                gsad_base.c
                gsad_cmd.c
                gsad_credentials.c
                gsad_gmp.c
                gsad_gmp_arguments.c
                gsad_gmp_request.c
                gsad_http.c
                gsad_http_handler.c
                gsad_i18n.c
                gsad_session.c
                gsad_settings.c
                gsad_user.c
                gsad_validator.c
                utils.c
                validator.c)

target_link_libraries (gsad ${LIBMICROHTTPD_LDFLAGS}
                            ${GTHREAD_LDFLAGS}
                            ${GLIB_LDFLAGS}
                            ${LIBXML_LDFLAGS}
                            ${LIBGCRYPT_LDFLAGS}
                            ${GNUTLS_LDFLAGS}
                            ${ZLIB_LDFLAGS}
                            ${BROTLI_LDFLAGS}
                            ${LIBGVM_BASE_LDFLAGS}
                            ${LIBGVM_UTIL_LDFLAGS}
                            ${LIBGVM_GMP_LDFLAGS}
                            ${LIBGVM_GMP_LDFLAGS}
                            ${CMAKE_THREAD_LIBS_INIT}
                            ${LINKER_HARDENING_FLAGS}
                       )
set_target_properties (gsad PROPERTIES LINKER_LANGUAGE C)

if (GSAD_VERSION)
  add_definitions (-DGSAD_VERSION="${GSAD_VERSION}")
endif (GSAD_VERSION)

if (GVM_SERVER_CERTIFICATE)
  add_definitions (-DGVM_SERVER_CERTIFICATE="${GVM_SERVER_CERTIFICATE}")
endif (GVM_SERVER_CERTIFICATE)

if (GVM_SERVER_KEY)
  add_definitions (-DGVM_SERVER_KEY="${GVM_SERVER_KEY}")
endif (GVM_SERVER_KEY)

if (GVM_CA_CERTIFICATE)
  add_definitions (-DGVM_CA_CERTIFICATE="${GVM_CA_CERTIFICATE}")
endif (GVM_CA_CERTIFICATE)

if (GVMD_RUN_DIR)
  add_definitions (-DGVMD_RUN_DIR="${GVMD_RUN_DIR}")
endif (GVMD_RUN_DIR)

if (GSAD_RUN_DIR)
  add_definitions (-DGSAD_RUN_DIR="${GSAD_RUN_DIR}")
endif (GSAD_RUN_DIR)

if (GSAD_PID_PATH)
  add_definitions (-DGSAD_PID_PATH="${GSAD_PID_PATH}")
endif (GSAD_PID_PATH)

if (GSAD_DATA_DIR)
  add_definitions (-DGSAD_DATA_DIR="${GSAD_DATA_DIR}")
endif (GSAD_DATA_DIR)


if (GSAD_CONFIG_DIR)
  add_definitions (-DGSAD_CONFIG_DIR="${GSAD_CONFIG_DIR}")
endif (GSAD_CONFIG_DIR)

if (GSAD_LOCALE_DIR)
  add_definitions (-DGSAD_LOCALE_DIR="${GSAD_LOCALE_DIR}")
endif (GSAD_LOCALE_DIR)

if (GSAD_CHROOT_LOCALE_DIR)
  add_definitions (-DGSAD_CHROOT_LOCALE_DIR="${GSAD_CHROOT_LOCALE_DIR}")
endif (GSAD_CHROOT_LOCALE_DIR)

add_definitions (-DGVM_OS_NAME="${CMAKE_SYSTEM}")
add_definitions (-DPREFIX="${CMAKE_INSTALL_PREFIX}")

## Install

install (TARGETS gsad
         RUNTIME DESTINATION ${SBINDIR}
         LIBRARY DESTINATION ${LIBDIR}
         ARCHIVE DESTINATION ${LIBDIR}/static)

## Static analysis

add_custom_target (cppcheck COMMENT "Running cppcheck..."
                   COMMAND sh -c \"cppcheck ${CMAKE_CURRENT_SOURCE_DIR}\")

add_custom_target (check COMMENT "Checking code...")
add_dependencies (check cppcheck)

## Tag files

set (C_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
add_custom_target (etags COMMENT "Building TAGS..."
                   COMMAND etags ${C_FILES})
add_custom_target (ctags COMMENT "Building tags..."
                   COMMAND ctags ${C_FILES})
add_custom_target (tags COMMENT "Building tags files...")
add_dependencies (tags etags ctags)

## Testing

if (BUILD_TESTING)
  find_package(cgreen REQUIRED)

  add_executable(gsad-validator-test EXCLUDE_FROM_ALL gsad_validator_test.c validator.c)

  target_link_libraries (gsad-validator-test ${CGREEN_LIBRARIES} ${GLIB_LDFLAGS})


  add_test (gsad-validator-test gsad-validator-test)

  add_custom_target (tests
                     DEPENDS
                     gsad-validator-test
                     )
endif(BUILD_TESTING)

if (ENABLE_COVERAGE)
  add_custom_target (coverage-html
                     COMMAND gcovr --html-details ${COVERAGE_DIR}/coverage.html
                     -r ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
  add_custom_target (coverage-xml
                     COMMAND gcovr --xml ${COVERAGE_DIR}/coverage.xml
                     -r ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
  add_custom_target (coverage DEPENDS coverage-xml coverage-html)
endif (ENABLE_COVERAGE)

add_custom_target (clean-coverage
                   COMMAND find . -name *.gcda -delete -or -name *.gcno -delete
                   COMMAND rm -f ${COVERAGE_DIR}/*)

## End
