# Match the minimum required version of onnx-mlir
cmake_minimum_required(VERSION 3.20.0)

project(raptor)

# Add symlink to PIM as accelerator in onnx-mlir
function(raptor_ensure_symlink link_path target_path)
  get_filename_component(link_parent "${link_path}" DIRECTORY)

  if(NOT EXISTS "${link_parent}")
    message(FATAL_ERROR "Directory not found: ${link_parent}")
  endif()

  if(NOT EXISTS "${link_path}")
    message(STATUS "Creating symlink ${link_path} -> ${target_path}")
    file(CREATE_LINK
        "${target_path}"
        "${link_path}"
        SYMBOLIC
    )
  endif()
endfunction()

raptor_ensure_symlink(
    "${CMAKE_CURRENT_SOURCE_DIR}/onnx-mlir/src/Accelerators/PIM"
    "${CMAKE_CURRENT_SOURCE_DIR}/src/PIM"
)
raptor_ensure_symlink(
    "${CMAKE_CURRENT_SOURCE_DIR}/onnx-mlir/test/accelerators/PIM"
    "${CMAKE_CURRENT_SOURCE_DIR}/test/PIM"
)

# Patch onnx-mlir sources for PIM accelerator support.
# Each patch searches for a context-aware anchor string rather than relying on
# line numbers, so that moderate upstream changes are tolerated.
function(raptor_apply_patch file_path anchor replacement description)
  file(READ "${file_path}" contents)

  # Already applied – replacement text is present
  string(FIND "${contents}" "${replacement}" already_applied_pos)
  if(NOT already_applied_pos EQUAL -1)
    message(STATUS "Patch already applied: ${description}")
    return()
  endif()

  # Anchor must exist for the patch to be applicable
  string(FIND "${contents}" "${anchor}" anchor_pos)
  if(anchor_pos EQUAL -1)
    message(FATAL_ERROR
      "Patch anchor not found – onnx-mlir may have changed.\n"
      "  Patch : ${description}\n"
      "  File  : ${file_path}\n"
      "  Anchor: ${anchor}"
    )
  endif()

  string(REPLACE "${anchor}" "${replacement}" patched "${contents}")
  file(WRITE "${file_path}" "${patched}")
  message(STATUS "Patch applied: ${description}")
endfunction()

set(ONNX_MLIR_DIR "${CMAKE_CURRENT_SOURCE_DIR}/onnx-mlir")

# Register PIM compiler options alongside NNPA
raptor_apply_patch(
  "${ONNX_MLIR_DIR}/src/Accelerators/Accelerator.hpp"
  "#include \"src/Accelerators/NNPA/Compiler/NNPACompilerOptions.hpp\""
  "#include \"src/Accelerators/NNPA/Compiler/NNPACompilerOptions.hpp\"\n#include \"src/Accelerators/PIM/Compiler/PimCompilerOptions.hpp\""
  "Add PIM compiler options include"
)

# Short-circuit output emission for the PIM accelerator
raptor_apply_patch(
  "${ONNX_MLIR_DIR}/src/Compiler/CompilerUtils.cpp"
  "switch (emissionTarget) {\n  case EmitObj: {"
  "if (llvm::is_contained(maccel, accel::Accelerator::Kind::PIM))\n    return CompilerSuccess;\n  switch (emissionTarget) {\n  case EmitObj: {"
  "Skip output emission for PIM accelerator"
)

add_subdirectory(onnx-mlir)
