cmake_minimum_required(VERSION 3.20)
project(goblin_scry VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_INSTALL_DOCDIR "share/doc/goblin-scry" CACHE PATH "Documentation directory")
include(GNUInstallDirs)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
option(GOBLIN_WITH_RDP "Build the FreeRDP 3 backend" ON)
option(GOBLIN_WITH_VNC "Build the LibVNCClient backend" ON)
option(GOBLIN_SANITIZE "Enable address and undefined behavior sanitizers" OFF)
if(GOBLIN_SANITIZE)
  add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer)
  add_link_options(-fsanitize=address,undefined)
endif()
add_library(goblin_core src/renderer.cpp src/input.cpp)
target_include_directories(goblin_core PUBLIC src)
target_compile_definitions(goblin_core PUBLIC GOBLIN_SCRY_VERSION="${PROJECT_VERSION}")
target_compile_options(goblin_core PRIVATE -Wall -Wextra -Wpedantic)
add_executable(goblin-scry src/main.cpp src/terminal.cpp src/session.cpp src/rdp.cpp src/vnc.cpp src/local.cpp)
target_link_libraries(goblin-scry PRIVATE goblin_core)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)
  # GCC 8 ships C++17 filesystem in a separate library (Kylin's native compiler).
  target_link_libraries(goblin_core PUBLIC stdc++fs)
endif()
target_compile_options(goblin-scry PRIVATE -Wall -Wextra -Wpedantic)
find_package(PkgConfig REQUIRED)
if(GOBLIN_WITH_RDP)
  pkg_check_modules(FREERDP REQUIRED IMPORTED_TARGET freerdp3>=3.0 winpr3>=3.0)
  target_link_libraries(goblin-scry PRIVATE PkgConfig::FREERDP)
  target_compile_definitions(goblin-scry PRIVATE GOBLIN_WITH_RDP)
endif()
if(GOBLIN_WITH_VNC)
  pkg_check_modules(VNC REQUIRED IMPORTED_TARGET libvncclient>=0.9.14)
  target_link_libraries(goblin-scry PRIVATE PkgConfig::VNC)
  target_compile_definitions(goblin-scry PRIVATE GOBLIN_WITH_VNC)
endif()
include(CTest)
if(BUILD_TESTING)
  add_executable(test-core tests/test_core.cpp)
  target_link_libraries(test-core PRIVATE goblin_core)
  add_test(NAME core COMMAND test-core)
  find_package(Python3 COMPONENTS Interpreter REQUIRED)
  add_test(NAME terminal COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/terminal_test.py $<TARGET_FILE:goblin-scry>)
  if(GOBLIN_WITH_VNC)
    add_executable(test-vnc tests/vnc_driver.cpp src/terminal.cpp src/session.cpp src/vnc.cpp)
    target_compile_definitions(test-vnc PRIVATE GOBLIN_WITH_VNC)
    target_link_libraries(test-vnc PRIVATE goblin_core PkgConfig::VNC)
    add_test(NAME vnc COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/vnc_test.py $<TARGET_FILE:test-vnc>)
    add_executable(test-local src/main.cpp src/terminal.cpp src/session.cpp src/rdp.cpp src/vnc.cpp src/local.cpp tests/local_socket.cpp)
    target_compile_definitions(test-local PRIVATE GOBLIN_WITH_VNC)
    target_compile_options(test-local PRIVATE -Wall -Wextra -Wpedantic)
    target_link_libraries(test-local PRIVATE goblin_core PkgConfig::VNC)
    add_test(NAME local COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/local_test.py $<TARGET_FILE:test-local>)
  endif()
  set_tests_properties(core terminal PROPERTIES TIMEOUT 30)
  if(GOBLIN_WITH_VNC)
    set_tests_properties(vnc PROPERTIES TIMEOUT 45)
    set_tests_properties(local PROPERTIES TIMEOUT 60)
  endif()
endif()
install(TARGETS goblin-scry RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES LICENSE README.md THIRD_PARTY.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(DIRECTORY licenses/ DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses)
