cmake_minimum_required(VERSION 3.10)

# set the project name
project (hin9)

find_package (Lua REQUIRED)
include_directories (${LUA_INCLUDE_DIR})

find_program (BASH_PROGRAM bash)

add_definitions (-D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -Wextra -Werror=vla -Wno-unused-parameter -fvisibility=hidden -fstrict-aliasing -Wstrict-aliasing=2)

set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)

include_directories ("src/hin/" "src/hin/http/" "src/system/" "external/basic/include")

option (USE_OPENSSL "Use openssl" ON)
option (USE_FCGI "Compile fastcgi support" ON)
option (USE_CGI "Compile cgi support" OFF)
option (USE_RPROXY "Compile reverse proxy support" ON)
option (USE_FFCALL "Use ffcall library for lua log function (more format specifiers)" OFF)
option (USE_ASAN "Use ASAN" OFF)

set (TARGET_HIN_LIBS ${TARGET_HIN_LIBS} uring)
set (TARGET_LIBS ${TARGET_LIBS} ${LUA_LIBRARIES} z)

if (USE_OPENSSL)
  add_definitions (-DHIN_USE_OPENSSL)
  set (TARGET_HIN_LIBS ${TARGET_HIN_LIBS} crypto ssl)
ENDIF()

if (USE_CGI)
  add_definitions (-DHIN_USE_CGI)
  set (other_src ${other_src} src/http/cgi/old_cgi.c)
ENDIF()

if (USE_FCGI)
  add_definitions (-DHIN_USE_FCGI)
  set (other_src ${other_src}
src/http/cgi/fcgi.c
src/http/cgi/fcgi_request.c
src/http/cgi/fcgi_response.c
src/http/cgi/fcgi_post.c
src/http/cgi/fcgi_socket.c
src/http/cgi/fcgi_util.c
src/http/cgi/fcgi_worker.c)
ENDIF()

if (USE_RPROXY)
  add_definitions (-DHIN_USE_RPROXY)
  set (other_src ${other_src} src/http/client/rproxy.c)
ENDIF()

if (USE_FFCALL)
  # disabled atm due to insufficient testing
  #add_definitions (-DHIN_USE_FFCALL)
  #set (TARGET_LIBS ${TARGET_LIBS} ffcall)
ENDIF()

IF (USE_ASAN)
  add_compile_options(-fsanitize=address)
  add_link_options(-fsanitize=address)
ENDIF()

set (external_src
external/basic/vfs/basic_vfs.c
external/basic/vfs/dir.c
external/basic/vfs/inotify.c
external/basic/vfs/stat.c
external/basic/vfs/path.c
external/basic/vfs/compat.c
external/basic/basic_args.c
external/basic/basic_endianness.c
external/basic/basic_hashtable.c
external/basic/basic_lists.c
external/basic/basic_pattern.c
)

set (hin_src
src/netcode/header.c
src/netcode/hin.c
src/netcode/ssl_data.c
src/netcode/ssl_init.c
src/netcode/connect.c
src/netcode/epoll.c
src/netcode/uring.c
src/netcode/server.c
src/netcode/listen.c
src/netcode/buffer.c
src/netcode/pipe.c
src/netcode/timer.c
src/netcode/utils.c

src/http/client/connect.c
src/http/client/headers.c
src/http/client/data.c
src/http/client/state.c
src/http/utils/string.c
src/http/cache/utils.c

src/http/server/client.c
src/http/server/file.c
src/http/server/read.c
src/http/server/response.c
src/http/server/headers.c
src/http/server/httpd.c
src/http/server/vhost.c
src/http/utils/misc.c
src/http/utils/filters.c
src/http/utils/timer.c
)

set (hin_exe
src/http/client/download.c
src/http/server/httpd_app.c
src/http/cgi/cgi_parse.c
src/http/cgi/cgi_common.c
src/http/cache/cache.c
src/system/args.c
src/system/console.c
src/system/signal.c
src/system/daemon.c
src/system/drop_user.c
src/system/helper.c
src/system/restart.c
src/system/main.c
src/lua/lua.c
src/lua/lua_callback.c
src/lua/lua_config.c
src/lua/lua_opt.c
src/lua/lua_utils.c
src/lua/lua_vfs.c
src/lua/lua_req.c
src/lua/lua_os.c
src/lua/lua_vhost.c
src/lua/lua_map.c
)

add_library (hin ${hin_src} ${external_src})
target_link_libraries (hin ${TARGET_HIN_LIBS})

add_executable (hinsightd ${hin_exe} ${other_src})
target_link_libraries (hinsightd hin ${TARGET_LIBS})

add_executable (hinsightd_pid_helper external/tools/pid_helper.c)

install(TARGETS hinsightd DESTINATION sbin)
install(TARGETS hinsightd_pid_helper DESTINATION libexec)

install(TARGETS hin)
install(DIRECTORY src/hin DESTINATION include)
install(DIRECTORY external/basic/include/ DESTINATION include/hin)

enable_testing()

if (BASH_PROGRAM)
  #add_test (mytest ${BASH_PROGRAM} ${CMAKE_CURRENT_SOURCE_DIR}/external/tests/minimal.sh)
  # the next version is way slower than running the test directly, spawns a new server for each test run but it is prettier and self documenting
  file(GLOB files "external/tests/tests/*.sh")
  foreach(file ${files})
    cmake_path(GET file FILENAME fn)
    set (test_path ../external/tests/tests/${fn})
    add_test(${fn} ${BASH_PROGRAM} ${CMAKE_CURRENT_SOURCE_DIR}/external/tests/run.sh ${test_path})
  endforeach()
endif (BASH_PROGRAM)

add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})

