cmake_minimum_required(VERSION 3.14)
project(LLS VERSION 1.0 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()

# --- SQLite ------------------------------------------------------------------
# Use the system SQLite if present, otherwise download the amalgamation.
find_package(SQLite3)

if(NOT SQLite3_FOUND)
  message(STATUS "System SQLite3 not found - fetching the amalgamation")
  include(FetchContent)
  if(POLICY CMP0135)
    cmake_policy(SET CMP0135 NEW)
  endif()
  FetchContent_Declare(sqlite3_amalgamation
    URL https://www.sqlite.org/2024/sqlite-amalgamation-3450100.zip)
  FetchContent_MakeAvailable(sqlite3_amalgamation)

  find_package(Threads REQUIRED)
  add_library(sqlite3_local STATIC ${sqlite3_amalgamation_SOURCE_DIR}/sqlite3.c)
  set_target_properties(sqlite3_local PROPERTIES POSITION_INDEPENDENT_CODE ON C_VISIBILITY_PRESET hidden)
  target_include_directories(sqlite3_local PUBLIC ${sqlite3_amalgamation_SOURCE_DIR})
  target_link_libraries(sqlite3_local PUBLIC Threads::Threads ${CMAKE_DL_LIBS})
  add_library(SQLite::SQLite3 ALIAS sqlite3_local)
endif()

# --- Warnings ----------------------------------------------------------------
function(lls_warnings target)
  if(MSVC)
    target_compile_options(${target} PRIVATE /W4)
  else()
    target_compile_options(${target} PRIVATE -Wall -Wextra -Wpedantic)
  endif()
endfunction()

# --- Core: the rules, shared by the prompt and the C API ---------------------
add_library(lls_core STATIC
  src/Database.cpp
  src/Status.cpp
  src/StringUtil.cpp
  src/Tracker.cpp
  src/Views.cpp
)
target_include_directories(lls_core PUBLIC include)
target_link_libraries(lls_core PUBLIC SQLite::SQLite3)
set_target_properties(lls_core PROPERTIES
  POSITION_INDEPENDENT_CODE ON
  CXX_VISIBILITY_PRESET hidden
  VISIBILITY_INLINES_HIDDEN ON)
lls_warnings(lls_core)

# --- C API: liblls_api.so / lls_api.dll (include/lls_api.h) ------------------
add_library(lls_api SHARED src/capi.cpp)
target_link_libraries(lls_api PRIVATE lls_core)
target_compile_definitions(lls_api PRIVATE LLS_BUILDING_API)
set_target_properties(lls_api PROPERTIES
  CXX_VISIBILITY_PRESET hidden
  VISIBILITY_INLINES_HIDDEN ON)
lls_warnings(lls_api)

# --- Application: the interactive prompt -------------------------------------
add_executable(lls
  src/main.cpp
  src/Completer.cpp
  src/Config.cpp
  src/Display.cpp
  src/ExternalEditor.cpp
  src/LineEditor.cpp
  src/Repl.cpp
  src/Table.cpp
  src/Terminal.cpp
  src/Tokenizer.cpp
  src/HomeDirectory.cpp
)
target_link_libraries(lls PRIVATE lls_core)
lls_warnings(lls)

# --- Example: the C API from C -----------------------------------------------
option(LLS_BUILD_EXAMPLES "Build the C API example" ON)
if(LLS_BUILD_EXAMPLES)
  add_executable(lls_example examples/example.c)
  target_link_libraries(lls_example PRIVATE lls_api)
  target_include_directories(lls_example PRIVATE include)
endif()
