cmake_minimum_required(VERSION 3.16)
project(velox VERSION 0.3.3 LANGUAGES C)
set(CMAKE_C_STANDARD 11)
option(VELOX_BUILD_GUI "Build graphical terminal (requires X11, Xft, libvterm)" ON)
option(VELOX_SANITIZE "Enable ASan and UBSan" OFF)
add_compile_definitions(_GNU_SOURCE)
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wformat=2 -Werror)
if(VELOX_SANITIZE)
  add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer)
  add_link_options(-fsanitize=address,undefined)
endif()
add_library(velox_posix pty/pty.c config/config.c session/session.c core/logo.c core/i18n.c core/layout.c ui/palette.c ui/settings.c ui/context.c)
target_include_directories(velox_posix PUBLIC ${PROJECT_SOURCE_DIR})
target_link_libraries(velox_posix PUBLIC util)
add_executable(velox-suggest tools/suggest.c)
include(CTest)
if(BUILD_TESTING)
  add_executable(i18n_tests tests/i18n_tests.c)
  target_compile_options(i18n_tests PRIVATE -UNDEBUG)
  target_link_libraries(i18n_tests PRIVATE velox_posix)
  add_test(NAME i18n COMMAND i18n_tests)
  add_executable(context_tests tests/context_tests.c)
  target_compile_options(context_tests PRIVATE -UNDEBUG)
  target_link_libraries(context_tests PRIVATE velox_posix)
  add_test(NAME context COMMAND context_tests)
  add_executable(posix_tests tests/posix_tests.c)
  target_compile_options(posix_tests PRIVATE -UNDEBUG)
  target_link_libraries(posix_tests PRIVATE velox_posix)
  add_test(NAME posix COMMAND posix_tests)
  add_executable(features_tests tests/features_tests.c)
  target_compile_options(features_tests PRIVATE -UNDEBUG)
  target_link_libraries(features_tests PRIVATE velox_posix)
  add_test(NAME features COMMAND features_tests ${PROJECT_SOURCE_DIR})
  add_test(NAME suggestions COMMAND python3 ${PROJECT_SOURCE_DIR}/tests/suggestions_tests.py ${PROJECT_SOURCE_DIR} $<TARGET_FILE:velox-suggest>)
  add_test(NAME commands_guide COMMAND python3 ${PROJECT_SOURCE_DIR}/tests/commands_tests.py ${PROJECT_SOURCE_DIR}/tools/commands)
endif()
if(VELOX_BUILD_GUI)
  find_package(PkgConfig REQUIRED)
  pkg_check_modules(DEPS REQUIRED IMPORTED_TARGET x11 xft fontconfig vterm>=0.1)
  add_library(velox_core terminal/terminal.c parser/utf8.c)
  target_include_directories(velox_core PUBLIC ${PROJECT_SOURCE_DIR})
  target_link_libraries(velox_core PUBLIC velox_posix PkgConfig::DEPS)
  add_library(velox_input ui/input.c ui/selection.c)
  target_link_libraries(velox_input PUBLIC velox_core)
  add_library(velox_fonts renderer/font_cache.c renderer/animation.c)
  target_include_directories(velox_fonts PUBLIC ${PROJECT_SOURCE_DIR})
  target_link_libraries(velox_fonts PUBLIC PkgConfig::DEPS velox_posix m)
  add_library(velox_platform platform/opacity.c platform/menu_surface.c)
  target_include_directories(velox_platform PUBLIC ${PROJECT_SOURCE_DIR})
  target_link_libraries(velox_platform PUBLIC PkgConfig::DEPS)
  add_executable(velox ui/main.c renderer/renderer.c)
  target_link_libraries(velox PRIVATE velox_input velox_fonts velox_platform)
  target_compile_definitions(velox PRIVATE VELOX_COMMANDS_SOURCE="${PROJECT_SOURCE_DIR}/tools/commands")
  if(BUILD_TESTING)
    add_executable(session_text_tests tests/session_text_tests.c)
    target_compile_options(session_text_tests PRIVATE -UNDEBUG)
    target_link_libraries(session_text_tests PRIVATE velox_core)
    add_test(NAME session_text COMMAND session_text_tests)
    add_executable(menu_surface_tests tests/menu_surface_tests.c)
    target_compile_options(menu_surface_tests PRIVATE -UNDEBUG)
    target_link_libraries(menu_surface_tests PRIVATE velox_platform)
    target_link_options(menu_surface_tests PRIVATE -Wl,--wrap=XCreateSimpleWindow -Wl,--wrap=XSelectInput -Wl,--wrap=XftDrawCreate -Wl,--wrap=XMapRaised -Wl,--wrap=XftDrawDestroy -Wl,--wrap=XDestroyWindow -Wl,--wrap=XCreatePixmap -Wl,--wrap=XCreateGC -Wl,--wrap=XSetWindowBackgroundPixmap -Wl,--wrap=XCopyArea -Wl,--wrap=XFlush -Wl,--wrap=XFreePixmap -Wl,--wrap=XFreeGC)
    add_test(NAME menu_surface COMMAND menu_surface_tests)
    add_executable(opacity_tests tests/opacity_tests.c)
    target_compile_options(opacity_tests PRIVATE -UNDEBUG)
    target_link_libraries(opacity_tests PRIVATE velox_platform)
    target_link_options(opacity_tests PRIVATE -Wl,--wrap=XInternAtom -Wl,--wrap=XGetSelectionOwner -Wl,--wrap=XQueryTree -Wl,--wrap=XChangeProperty -Wl,--wrap=XFlush)
    add_test(NAME opacity COMMAND opacity_tests)
    add_executable(core_tests tests/core_tests.c)
    target_compile_options(core_tests PRIVATE -UNDEBUG)
    target_link_libraries(core_tests PRIVATE velox_core)
    add_test(NAME core COMMAND core_tests)
    add_executable(selection_tests tests/selection_tests.c)
    target_compile_options(selection_tests PRIVATE -UNDEBUG)
    target_link_libraries(selection_tests PRIVATE velox_input)
    add_test(NAME selection COMMAND selection_tests)
    add_executable(pty_burst_tests tests/pty_burst_tests.c)
    target_compile_options(pty_burst_tests PRIVATE -UNDEBUG)
    target_link_libraries(pty_burst_tests PRIVATE velox_input)
    add_test(NAME pty_burst COMMAND pty_burst_tests)
    set_tests_properties(pty_burst PROPERTIES TIMEOUT 10)
    add_executable(input_stress_tests tests/input_stress_tests.c)
    target_compile_options(input_stress_tests PRIVATE -UNDEBUG)
    target_link_libraries(input_stress_tests PRIVATE velox_input)
    add_test(NAME input_stress COMMAND input_stress_tests)
    set_tests_properties(input_stress PROPERTIES TIMEOUT 25)
    add_executable(input_tests tests/input_tests.c)
    target_compile_options(input_tests PRIVATE -UNDEBUG)
    target_link_libraries(input_tests PRIVATE velox_input)
    add_test(NAME input COMMAND input_tests)
    add_executable(unicode_tests tests/unicode_tests.c)
    target_compile_options(unicode_tests PRIVATE -UNDEBUG)
    target_link_libraries(unicode_tests PRIVATE velox_core)
    add_test(NAME unicode COMMAND unicode_tests)
    add_executable(font_tests tests/font_tests.c)
    target_compile_options(font_tests PRIVATE -UNDEBUG)
    target_link_libraries(font_tests PRIVATE velox_fonts)
    add_test(NAME fonts COMMAND font_tests)
    add_executable(animation_tests tests/animation_tests.c)
    target_compile_options(animation_tests PRIVATE -UNDEBUG)
    target_link_libraries(animation_tests PRIVATE velox_fonts)
    target_link_options(animation_tests PRIVATE -Wl,--wrap=calloc)
    add_test(NAME animations COMMAND animation_tests)
    add_executable(renderer_tests tests/renderer_tests.c renderer/renderer.c)
    target_compile_options(renderer_tests PRIVATE -UNDEBUG)
    target_link_libraries(renderer_tests PRIVATE velox_core velox_fonts)
    target_link_options(renderer_tests PRIVATE
      -Wl,--wrap=XftFontOpenPattern -Wl,--wrap=XftFontClose -Wl,--wrap=XftCharExists
      -Wl,--wrap=XftDrawSetClipRectangles -Wl,--wrap=XftDrawSetClip
      -Wl,--wrap=XftDrawString32 -Wl,--wrap=XftDrawStringUtf8 -Wl,--wrap=XftDrawRect -Wl,--wrap=XFlush)
    add_test(NAME renderer_geometry COMMAND renderer_tests)
    set_tests_properties(input PROPERTIES TIMEOUT 20)
  endif()
  add_executable(history_bench benchmarks/history_bench.c)
  target_link_libraries(history_bench PRIVATE velox_core)
  target_link_options(history_bench PRIVATE -Wl,--wrap=realloc)
  add_executable(parser_bench benchmarks/parser_bench.c)
  target_link_libraries(parser_bench PRIVATE velox_core)
  install(TARGETS velox velox-suggest RUNTIME DESTINATION bin)
  install(PROGRAMS tools/commands DESTINATION bin)
  install(FILES shell/bash.sh DESTINATION share/velox/shell)
  install(FILES packaging/velox.desktop DESTINATION share/applications)
  install(FILES assets/velox.svg DESTINATION share/icons/hicolor/scalable/apps)
  install(FILES config/config.toml DESTINATION share/velox)
  install(DIRECTORY assets/ DESTINATION share/velox/assets)
  install(DIRECTORY themes/ DESTINATION share/velox/themes)
endif()
