cmake_minimum_required(VERSION 3.15)
project(s100p_stage3_vlm CXX)

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

option(STAGE3_PROTOCOL_ONLY
       "Build only the host-testable protocol and service components" ON)

function(stage3_strict target)
  if(MSVC)
    target_compile_options(${target} PRIVATE /W4 /WX)
  else()
    target_compile_options(${target} PRIVATE -Wall -Wextra -Werror)
  endif()
endfunction()

find_package(nlohmann_json REQUIRED)

add_library(stage3_protocol STATIC src/vlm_protocol.cpp)
target_include_directories(stage3_protocol PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc)
target_link_libraries(stage3_protocol PUBLIC nlohmann_json::nlohmann_json)
stage3_strict(stage3_protocol)

add_library(stage3_vlm_service STATIC src/vlm_service.cpp)
target_include_directories(stage3_vlm_service PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/inc)
target_link_libraries(stage3_vlm_service PUBLIC stage3_protocol)
stage3_strict(stage3_vlm_service)

add_library(stage3_http STATIC src/vlm_http.cpp)
target_include_directories(stage3_http PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc)
target_link_libraries(stage3_http PUBLIC stage3_vlm_service)
stage3_strict(stage3_http)

if(UNIX)
  add_library(stage3_http_server_io STATIC src/vlm_web_server.cpp)
  target_compile_definitions(stage3_http_server_io PRIVATE
    STAGE3_HTTP_SERVER_NO_MAIN)
  target_include_directories(stage3_http_server_io PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/inc)
  target_link_libraries(stage3_http_server_io PUBLIC stage3_http)
  stage3_strict(stage3_http_server_io)
endif()

add_library(stage3_gemma4_backend STATIC src/gemma4_backend.cpp)
target_include_directories(stage3_gemma4_backend PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/inc)
target_link_libraries(stage3_gemma4_backend PUBLIC stage3_vlm_service)
stage3_strict(stage3_gemma4_backend)

if(NOT STAGE3_PROTOCOL_ONLY)
  set(GEMMA4_SAMPLE_ROOT
      "/root/rdk_model_zoo/samples/llm/gemma4-e2b"
      CACHE PATH "Path to the pinned Model Zoo Gemma4-E2B sample")
  set(GEMMA4_RUNTIME_ROOT "${GEMMA4_SAMPLE_ROOT}/runtime/cpp")
  set(TOKENIZERS_CPP_ROOT "${GEMMA4_SAMPLE_ROOT}/third_party/tokenizers-cpp"
      CACHE PATH "Path to the installed tokenizers-cpp source")

  if(NOT EXISTS "${GEMMA4_RUNTIME_ROOT}/inc/gemma4_text_engine.hpp")
    message(FATAL_ERROR
      "Gemma4 runtime not found under ${GEMMA4_RUNTIME_ROOT}")
  endif()
  if(NOT EXISTS "${TOKENIZERS_CPP_ROOT}/CMakeLists.txt")
    message(FATAL_ERROR
      "tokenizers-cpp is missing; run the official installer first")
  endif()

  find_path(HOBOT_INCLUDE_DIR hobot/dnn/hb_dnn.h
    PATHS /usr/hobot/include /usr/include NO_DEFAULT_PATH)
  find_library(DNN_LIB dnn
    PATHS /usr/hobot/lib /usr/lib/aarch64-linux-gnu NO_DEFAULT_PATH)
  find_library(HBUCP_LIB hbucp
    PATHS /usr/hobot/lib /usr/lib/aarch64-linux-gnu NO_DEFAULT_PATH)
  if(NOT HOBOT_INCLUDE_DIR OR NOT DNN_LIB OR NOT HBUCP_LIB)
    message(FATAL_ERROR
      "Horizon DNN/HBUCP headers or libraries were not found under /usr/hobot")
  endif()

  find_package(OpenCV REQUIRED COMPONENTS core imgcodecs imgproc)
  find_package(gflags REQUIRED)
  add_subdirectory(${TOKENIZERS_CPP_ROOT}
                   ${CMAKE_CURRENT_BINARY_DIR}/tokenizers-cpp)

  add_library(gemma4_runtime STATIC
    ${GEMMA4_RUNTIME_ROOT}/src/gemma4_native_tokenizer.cpp
    ${GEMMA4_RUNTIME_ROOT}/src/gemma4_tokenizer.cpp
    ${GEMMA4_RUNTIME_ROOT}/src/gemma4_embeddings.cpp
    ${GEMMA4_RUNTIME_ROOT}/src/gemma4_kv_cache.cpp
    ${GEMMA4_RUNTIME_ROOT}/src/gemma4_text_engine.cpp
    ${GEMMA4_RUNTIME_ROOT}/src/gemma4_vision_preprocess.cpp
    ${GEMMA4_RUNTIME_ROOT}/src/gemma4_vision_engine.cpp)
  target_compile_definitions(gemma4_runtime PUBLIC SOC_S100P)
  target_include_directories(gemma4_runtime PUBLIC
    ${HOBOT_INCLUDE_DIR}
    ${OpenCV_INCLUDE_DIRS}
    ${GEMMA4_RUNTIME_ROOT}/inc
    ${TOKENIZERS_CPP_ROOT}/include)
  target_link_libraries(gemma4_runtime PUBLIC
    ${DNN_LIB}
    ${HBUCP_LIB}
    ${OpenCV_LIBS}
    ${CMAKE_DL_LIBS}
    tokenizers_cpp
    nlohmann_json::nlohmann_json)

  target_compile_definitions(stage3_gemma4_backend PRIVATE
    STAGE3_WITH_GEMMA4_RUNTIME)
  target_link_libraries(stage3_gemma4_backend PRIVATE gemma4_runtime)

  add_executable(gemma4_vlm_web src/vlm_web_server.cpp)
  target_link_libraries(gemma4_vlm_web PRIVATE
    stage3_http
    stage3_gemma4_backend
    gflags)
  stage3_strict(gemma4_vlm_web)

  set(CMAKE_BUILD_RPATH "/usr/hobot/lib")
  set(CMAKE_INSTALL_RPATH "/usr/hobot/lib")
endif()
