# =================================================================
# Img2Num Core (C++)
# =================================================================
project(Img2Num
  LANGUAGES CXX
  # Don't change the inline comment below - release-please needs it
  VERSION 0.2.0 # x-release-please-version
)

include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

file(GLOB_RECURSE CORE_SRC
  "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
)

message(STATUS ${CMAKE_BINARY_DIR})

file(GLOB WGSL_SHADERS CONFIGURE_DEPENDS
    ${CMAKE_CURRENT_SOURCE_DIR}/src/internal/resources/*.wgsl
)

# Mark embedded_shaders.h as GENERATED by a script
set(EMBEDDED_SHADERS_OUT "${CMAKE_BINARY_DIR}/embedded_shaders.h")
set_source_files_properties(${EMBEDDED_SHADERS_OUT} PROPERTIES GENERATED TRUE)

find_package(Python3 COMPONENTS Interpreter REQUIRED)

add_custom_target(Img2Num_shaders ALL
    COMMAND "${Python3_EXECUTABLE}" ${CMAKE_CURRENT_SOURCE_DIR}/tools/embed_shaders.py
            ${CMAKE_CURRENT_SOURCE_DIR}/src/internal/resources
            ${EMBEDDED_SHADERS_OUT}
    DEPENDS 
        ${WGSL_SHADERS}
        ${CMAKE_CURRENT_SOURCE_DIR}/tools/embed_shaders.py
    VERBATIM
)

add_library(Img2Num ${CORE_SRC})

# =================================================================
# spdlog (debug logging)
# Logging level (compile-time stripping via SPDLOG_ACTIVE_LEVEL)
#
#   AUTO (default): pick a level from the build type:
#     Debug              -> TRACE  (everything)
#     Release/MinSizeRel -> OFF    (fully stripped)
#     RelWithDebInfo/etc -> INFO
#   Or force a level: -DIMG2NUM_LOG_LEVEL=TRACE|DEBUG|INFO|WARN|ERROR|CRITICAL|OFF
# =================================================================
block()
  set(CMAKE_EXPORT_COMPILE_COMMANDS OFF)
  add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../third_party/spdlog"
                    "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/spdlog/build/"
                    EXCLUDE_FROM_ALL)
  target_link_libraries(Img2Num PRIVATE spdlog::spdlog_header_only)
  set(IMG2NUM_LOG_LEVEL "AUTO" CACHE STRING "Compile-time spdlog level for Img2Num")
  set_property(CACHE IMG2NUM_LOG_LEVEL PROPERTY STRINGS
      AUTO TRACE DEBUG INFO WARN ERROR CRITICAL OFF)

  string(TOUPPER "${IMG2NUM_LOG_LEVEL}" _IMG2NUM_LOG_LEVEL)

  if(_IMG2NUM_LOG_LEVEL STREQUAL "AUTO")
    if(CMAKE_BUILD_TYPE STREQUAL "Debug")
      set(_IMG2NUM_LOG_LEVEL "TRACE")
    elseif(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
      set(_IMG2NUM_LOG_LEVEL "OFF")
    else()
      set(_IMG2NUM_LOG_LEVEL "INFO")
    endif()
  endif()

  # Map to spdlog's numeric level macros — these names are spdlog's, keep them.
  if(_IMG2NUM_LOG_LEVEL MATCHES "^(TRACE|DEBUG|INFO|WARN|ERROR|CRITICAL|OFF)$")
    set(_IMG2NUM_SPDLOG_LEVEL "SPDLOG_LEVEL_${_IMG2NUM_LOG_LEVEL}")
  else()
    message(FATAL_ERROR "IMG2NUM_LOG_LEVEL='${IMG2NUM_LOG_LEVEL}' is not one of AUTO/TRACE/DEBUG/INFO/WARN/ERROR/CRITICAL/OFF")
  endif()

  message(STATUS "Img2Num log level: ${_IMG2NUM_LOG_LEVEL} (${_IMG2NUM_SPDLOG_LEVEL})")

  target_compile_definitions(Img2Num PRIVATE
    SPDLOG_ACTIVE_LEVEL=${_IMG2NUM_SPDLOG_LEVEL}
  )

  install(TARGETS spdlog_header_only EXPORT Img2NumTargets)
endblock()

target_compile_options(Img2Num PRIVATE ${IMG2NUM_STRICT_CXX_FLAGS})

set_target_properties(Img2Num PROPERTIES
  VERSION ${PROJECT_VERSION}
  SOVERSION 1
)

set_property(TARGET Img2Num PROPERTY POSITION_INDEPENDENT_CODE ON)

add_dependencies(Img2Num Img2Num_shaders)

target_sources(Img2Num PRIVATE ${EMBEDDED_SHADERS_OUT})

target_include_directories(Img2Num
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/img2num>
  PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/include/internal
    ${CMAKE_BINARY_DIR}
)

if (EMSCRIPTEN)
  message("using emdawnwebgpu port")
  target_compile_options(Img2Num PRIVATE "--use-port=emdawnwebgpu")
  target_link_options(Img2Num PRIVATE "--use-port=emdawnwebgpu" "SHELL:-s ASYNCIFY=1")
else()

  # Dawn WebGPU (prefer installed Dawn over building it — baked into Dockerfile.dev)
  block(PROPAGATE Dawn_FOUND DAWN_INCLUDE_DIR)
    find_package(Dawn QUIET)
    if(Dawn_FOUND)
      message("Found system Dawn")
    else()
      message("Building Dawn from third_party")
      set(DAWN_SUPPORTS_GLFW_FOR_WINDOWING OFF CACHE BOOL "Disable GLFW support for windowing" FORCE)
      set(DAWN_USE_X11 OFF CACHE BOOL "Disable X11 support" FORCE)
      set(DAWN_FETCH_DEPENDENCIES ON)
      # Keep Dawn's TUs out of compile_commands.json
      set(CMAKE_EXPORT_COMPILE_COMMANDS OFF)
      add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../third_party/dawn" "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/dawn/build/" EXCLUDE_FROM_ALL)
    endif()
  endblock()

  # PUBLIC: only expose the directory that contains img2num.h
  # PRIVATE: internal headers and Dawn
  target_include_directories(Img2Num
    PUBLIC
      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    PRIVATE
      $<BUILD_INTERFACE:${DAWN_INCLUDE_DIR}>
      ${CMAKE_CURRENT_SOURCE_DIR}/include/internal
  )

  target_link_libraries(Img2Num PRIVATE $<BUILD_INTERFACE:webgpu_dawn>)
endif()

# --- Install targets for packaging ---
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/Img2NumConfigVersion.cmake"
  VERSION ${PROJECT_VERSION}
  COMPATIBILITY SameMajorVersion
)

configure_package_config_file(
  ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Img2NumConfig.cmake.in
  ${CMAKE_CURRENT_BINARY_DIR}/Img2NumConfig.cmake
  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Img2Num
)

install(FILES
  ${CMAKE_CURRENT_BINARY_DIR}/Img2NumConfig.cmake
  ${CMAKE_CURRENT_BINARY_DIR}/Img2NumConfigVersion.cmake
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Img2Num
)

install(TARGETS Img2Num
  EXPORT Img2NumTargets
    LIBRARY DESTINATION  ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION  ${CMAKE_INSTALL_LIBDIR}
    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/img2num
)

install(EXPORT Img2NumTargets
  FILE Img2NumTargets.cmake
  NAMESPACE Img2Num::
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Img2Num
)

install(DIRECTORY include/
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/img2num
  REGEX "^.*/internal/.*" EXCLUDE
)

message(STATUS "Core library configured with ${CORE_SRC}")
