#include "napi.h"
#include "test_helper.h"

using namespace Napi;

class FuncRefObject : public Napi::ObjectWrap<FuncRefObject> {
 public:
  FuncRefObject(const Napi::CallbackInfo& info)
      : Napi::ObjectWrap<FuncRefObject>(info) {
    Napi::Env env = info.Env();
    int argLen = info.Length();
    if (argLen <= 0 || !info[0].IsNumber()) {
      Napi::TypeError::New(env, "First param should be a number")
          .ThrowAsJavaScriptException();
      return;
    }
    Napi::Number value = info[0].As<Napi::Number>();
    this->_value = value.Int32Value();
  }

  Napi::Value GetValue(const Napi::CallbackInfo& info) {
    int value = this->_value;
    return Napi::Number::New(info.Env(), value);
  }

 private:
  int _value;
};

namespace {

Value ConstructRefFromExisitingRef(const CallbackInfo& info) {
  EscapableHandleScope scope(info.Env());
  FunctionReference ref;
  FunctionReference movedRef;
  ref.Reset(info[0].As<Function>());
  movedRef = std::move(ref);

  return scope.Escape(MaybeUnwrap(movedRef({})));
}

Value CallWithVectorArgs(const CallbackInfo& info) {
  EscapableHandleScope scope(info.Env());
  std::vector<napi_value> newVec;
  FunctionReference ref;
  ref.Reset(info[0].As<Function>());

  for (int i = 1; i < (int)info.Length(); i++) {
    newVec.push_back(info[i]);
  }
  return scope.Escape(MaybeUnwrap(ref.Call(newVec)));
}

Value CallWithInitList(const CallbackInfo& info) {
  EscapableHandleScope scope(info.Env());
  FunctionReference ref;
  ref.Reset(info[0].As<Function>());

  return scope.Escape(MaybeUnwrap(ref.Call({info[1], info[2], info[3]})));
}

Value CallWithRecvInitList(const CallbackInfo& info) {
  EscapableHandleScope scope(info.Env());
  FunctionReference ref;
  ref.Reset(info[0].As<Function>());

  return scope.Escape(
      MaybeUnwrap(ref.Call(info[1], {info[2], info[3], info[4]})));
}

Value CallWithRecvVector(const CallbackInfo& info) {
  EscapableHandleScope scope(info.Env());
  FunctionReference ref;
  std::vector<napi_value> newVec;
  ref.Reset(info[0].As<Function>());

  for (int i = 2; i < (int)info.Length(); i++) {
    newVec.push_back(info[i]);
  }
  return scope.Escape(MaybeUnwrap(ref.Call(info[1], newVec)));
}

Value CallWithRecvArgc(const CallbackInfo& info) {
  EscapableHandleScope scope(info.Env());
  FunctionReference ref;
  ref.Reset(info[0].As<Function>());

  size_t argLength = info.Length() > 2 ? info.Length() - 2 : 0;
  std::unique_ptr<napi_value[]> args{argLength > 0 ? new napi_value[argLength]
                                                   : nullptr};
  for (size_t i = 0; i < argLength; ++i) {
    args[i] = info[i + 2];
  }

  return scope.Escape(MaybeUnwrap(ref.Call(info[1], argLength, args.get())));
}

Value MakeAsyncCallbackWithInitList(const Napi::CallbackInfo& info) {
  Napi::FunctionReference ref;
  ref.Reset(info[0].As<Function>());

  Napi::AsyncContext context(info.Env(), "func_ref_resources", {});

  return MaybeUnwrap(
      ref.MakeCallback(Napi::Object::New(info.Env()), {}, context));
}

Value MakeAsyncCallbackWithVector(const Napi::CallbackInfo& info) {
  Napi::FunctionReference ref;
  ref.Reset(info[0].As<Function>());
  std::vector<napi_value> newVec;
  Napi::AsyncContext context(info.Env(), "func_ref_resources", {});

  for (int i = 1; i < (int)info.Length(); i++) {
    newVec.push_back(info[i]);
  }

  return MaybeUnwrap(
      ref.MakeCallback(Napi::Object::New(info.Env()), newVec, context));
}

Value MakeAsyncCallbackWithArgv(const Napi::CallbackInfo& info) {
  Napi::FunctionReference ref;
  ref.Reset(info[0].As<Function>());

  size_t argLength = info.Length() > 1 ? info.Length() - 1 : 0;
  std::unique_ptr<napi_value[]> args{argLength > 0 ? new napi_value[argLength]
                                                   : nullptr};
  for (size_t i = 0; i < argLength; ++i) {
    args[i] = info[i + 1];
  }

  Napi::AsyncContext context(info.Env(), "func_ref_resources", {});
  return MaybeUnwrap(ref.MakeCallback(Napi::Object::New(info.Env()),
                                      argLength,
                                      argLength > 0 ? args.get() : nullptr,
                                      context));
}

Value CreateFunctionReferenceUsingNew(const Napi::CallbackInfo& info) {
  Napi::Function func = ObjectWrap<FuncRefObject>::DefineClass(
      info.Env(),
      "MyObject",
      {ObjectWrap<FuncRefObject>::InstanceMethod("getValue",
                                                 &FuncRefObject::GetValue)});
  Napi::FunctionReference* constructor = new Napi::FunctionReference();
  *constructor = Napi::Persistent(func);

  return MaybeUnwrapOr(constructor->New({info[0].As<Number>()}), Object());
}

Value CreateFunctionReferenceUsingNewVec(const Napi::CallbackInfo& info) {
  Napi::Function func = ObjectWrap<FuncRefObject>::DefineClass(
      info.Env(),
      "MyObject",
      {ObjectWrap<FuncRefObject>::InstanceMethod("getValue",
                                                 &FuncRefObject::GetValue)});
  Napi::FunctionReference* constructor = new Napi::FunctionReference();
  *constructor = Napi::Persistent(func);
  std::vector<napi_value> newVec;
  newVec.push_back(info[0]);

  return MaybeUnwrapOr(constructor->New(newVec), Object());
}

Value Call(const CallbackInfo& info) {
  EscapableHandleScope scope(info.Env());
  FunctionReference ref;
  ref.Reset(info[0].As<Function>());

  return scope.Escape(MaybeUnwrapOr(ref.Call({}), Value()));
}

Value Construct(const CallbackInfo& info) {
  EscapableHandleScope scope(info.Env());
  FunctionReference ref;
  ref.Reset(info[0].As<Function>());

  return scope.Escape(MaybeUnwrapOr(ref.New({}), Object()));
}
}  // namespace

Object InitFunctionReference(Env env) {
  Object exports = Object::New(env);
  exports["CreateFuncRefWithNew"] =
      Function::New(env, CreateFunctionReferenceUsingNew);
  exports["CreateFuncRefWithNewVec"] =
      Function::New(env, CreateFunctionReferenceUsingNewVec);
  exports["CallWithRecvArgc"] = Function::New(env, CallWithRecvArgc);
  exports["CallWithRecvVector"] = Function::New(env, CallWithRecvVector);
  exports["CallWithRecvInitList"] = Function::New(env, CallWithRecvInitList);
  exports["CallWithInitList"] = Function::New(env, CallWithInitList);
  exports["CallWithVec"] = Function::New(env, CallWithVectorArgs);
  exports["ConstructWithMove"] =
      Function::New(env, ConstructRefFromExisitingRef);
  exports["AsyncCallWithInitList"] =
      Function::New(env, MakeAsyncCallbackWithInitList);
  exports["AsyncCallWithVector"] =
      Function::New(env, MakeAsyncCallbackWithVector);
  exports["AsyncCallWithArgv"] = Function::New(env, MakeAsyncCallbackWithArgv);
  exports["call"] = Function::New(env, Call);
  exports["construct"] = Function::New(env, Construct);

  return exports;
}
