// Tests adding buffer copy with offset -- Target to Host (read path) --  nodes
// and submitting the graph.

#include "../graph_common.hpp"

int main() {
  queue Queue{};

  using T = int;

  std::vector<T> DataA(Size), DataB(Size);
  std::iota(DataA.begin(), DataA.end(), 1);
  std::iota(DataB.begin(), DataB.end(), 1000);

  std::vector<T> ReferenceA(Size), ReferenceB(Size);
  for (size_t i = 0; i < Size; i++) {
    ReferenceA[i] = DataA[i];
    if (i < (Size - Offset))
      ReferenceB[i] = DataA[i + Offset];
    else
      ReferenceB[i] = DataB[i];
  }

  buffer<T, 1> BufferA(DataA.data(), range<1>(Size));
  BufferA.set_write_back(false);

  {
    exp_ext::command_graph Graph{
        Queue.get_context(),
        Queue.get_device(),
        {exp_ext::property::graph::assume_buffer_outlives_graph{}}};

    auto NodeA = add_node(Graph, Queue, [&](handler &CGH) {
      auto AccA = BufferA.get_access<access::mode::read>(
          CGH, range<1>(Size - Offset), id<1>(Offset));
      CGH.copy(AccA, DataB.data());
    });

    auto GraphExec = Graph.finalize();
    Queue.submit([&](handler &CGH) { CGH.ext_oneapi_graph(GraphExec); }).wait();
  }

  for (size_t i = 0; i < Size; i++) {
    assert(check_value(i, ReferenceA[i], DataA[i], "DataA"));
    assert(check_value(i, ReferenceB[i], DataB[i], "DataB"));
  }

  return 0;
}
