#include <Differ.h>
#include "Utils.h"

namespace sharedjsi
{

Function dittoffi_differ_new(Runtime &runtime)
{
  return Function::createFromHostFunction(
                                          runtime,
                                          PropNameID::forAscii(runtime, STRINGIFIED_FUNC_NAME()),
                                          0,
                                          [](Runtime &runtime,
                                             const Value &thisValue,
                                             const Value *arguments,
                                             size_t count) -> Value {
                                               dittoffi_differ_t *ffiDiffer = ::dittoffi_differ_new();
                                               return cPointerToJSPointerObject<dittoffi_differ_t>(runtime, ffiDiffer);
                                             });
}

Function dittoffi_differ_free(Runtime &runtime)
{
  return Function::createFromHostFunction(
                                          runtime,
                                          PropNameID::forAscii(runtime, STRINGIFIED_FUNC_NAME()),
                                          1,
                                          [](Runtime &runtime,
                                             const Value &thisValue,
                                             const Value *arguments,
                                             size_t count) -> Value {
                                               dittoffi_differ_t *ffiDiffer = jsPointerObjectToCPointer<dittoffi_differ_t>(runtime, arguments[0]);
                                               ::dittoffi_differ_free(ffiDiffer);
                                               return {};
                                             });
}

Function dittoffi_differ_diff(Runtime &runtime)
{
  return Function::createFromHostFunction(
                                          runtime,
                                          PropNameID::forAscii(runtime, STRINGIFIED_FUNC_NAME()),
                                          2,
                                          [](Runtime &runtime,
                                             const Value &thisValue,
                                             const Value *arguments,
                                             size_t count) -> Value {
                                               dittoffi_differ_t *ffiDiffer = jsPointerObjectToCPointer<dittoffi_differ_t>(runtime, arguments[0]);

                                               auto items_vec = jsPointerArrayToVector<dittoffi_query_result_item_t *>(runtime, arguments[1]);
                                               slice_ref_dittoffi_query_result_item_ptr items = borrowVecAsRefSlice(items_vec);
                                               
                                               auto cborBlob = ::dittoffi_differ_diff(ffiDiffer, items);
                                               return cSlicedBoxToJSSlicedBox(runtime, cborBlob);
                                             });
}
}
