#include "base_object-inl.h"
#include "node_buffer.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_internals.h"
#include "util-inl.h"

namespace node {

using v8::Array;
using v8::ArrayBuffer;
using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Isolate;
using v8::Just;
using v8::Local;
using v8::Maybe;
using v8::MaybeLocal;
using v8::Nothing;
using v8::Object;
using v8::SharedArrayBuffer;
using v8::String;
using v8::Value;
using v8::ValueDeserializer;
using v8::ValueSerializer;

namespace serdes {

class SerializerContext : public BaseObject,
                          public ValueSerializer::Delegate {
 public:
  SerializerContext(Environment* env,
                    Local<Object> wrap);

  ~SerializerContext() override = default;

  void ThrowDataCloneError(Local<String> message) override;
  Maybe<bool> WriteHostObject(Isolate* isolate, Local<Object> object) override;
  Maybe<uint32_t> GetSharedArrayBufferId(
      Isolate* isolate, Local<SharedArrayBuffer> shared_array_buffer) override;

  static void SetTreatArrayBufferViewsAsHostObjects(
      const FunctionCallbackInfo<Value>& args);

  static void New(const FunctionCallbackInfo<Value>& args);
  static void WriteHeader(const FunctionCallbackInfo<Value>& args);
  static void WriteValue(const FunctionCallbackInfo<Value>& args);
  static void ReleaseBuffer(const FunctionCallbackInfo<Value>& args);
  static void TransferArrayBuffer(const FunctionCallbackInfo<Value>& args);
  static void WriteUint32(const FunctionCallbackInfo<Value>& args);
  static void WriteUint64(const FunctionCallbackInfo<Value>& args);
  static void WriteDouble(const FunctionCallbackInfo<Value>& args);
  static void WriteRawBytes(const FunctionCallbackInfo<Value>& args);

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(SerializerContext)
  SET_SELF_SIZE(SerializerContext)

 private:
  ValueSerializer serializer_;
};

class DeserializerContext : public BaseObject,
                            public ValueDeserializer::Delegate {
 public:
  DeserializerContext(Environment* env,
                      Local<Object> wrap,
                      Local<Value> buffer);

  ~DeserializerContext() override = default;

  MaybeLocal<Object> ReadHostObject(Isolate* isolate) override;

  static void New(const FunctionCallbackInfo<Value>& args);
  static void ReadHeader(const FunctionCallbackInfo<Value>& args);
  static void ReadValue(const FunctionCallbackInfo<Value>& args);
  static void TransferArrayBuffer(const FunctionCallbackInfo<Value>& args);
  static void GetWireFormatVersion(const FunctionCallbackInfo<Value>& args);
  static void ReadUint32(const FunctionCallbackInfo<Value>& args);
  static void ReadUint64(const FunctionCallbackInfo<Value>& args);
  static void ReadDouble(const FunctionCallbackInfo<Value>& args);
  static void ReadRawBytes(const FunctionCallbackInfo<Value>& args);

  SET_NO_MEMORY_INFO()
  SET_MEMORY_INFO_NAME(DeserializerContext)
  SET_SELF_SIZE(DeserializerContext)

 private:
  const uint8_t* data_;
  const size_t length_;

  ValueDeserializer deserializer_;
};

SerializerContext::SerializerContext(Environment* env, Local<Object> wrap)
  : BaseObject(env, wrap),
    serializer_(env->isolate(), this) {
  MakeWeak();
}

void SerializerContext::ThrowDataCloneError(Local<String> message) {
  Local<Value> args[1] = { message };
  Local<Value> get_data_clone_error =
      object()->Get(env()->context(),
                    env()->get_data_clone_error_string())
                      .ToLocalChecked();

  CHECK(get_data_clone_error->IsFunction());
  MaybeLocal<Value> error =
      get_data_clone_error.As<Function>()->Call(env()->context(),
                                                object(),
                                                arraysize(args),
                                                args);

  if (error.IsEmpty()) return;

  env()->isolate()->ThrowException(error.ToLocalChecked());
}

Maybe<uint32_t> SerializerContext::GetSharedArrayBufferId(
    Isolate* isolate, Local<SharedArrayBuffer> shared_array_buffer) {
  Local<Value> args[1] = { shared_array_buffer };
  Local<Value> get_shared_array_buffer_id =
      object()->Get(env()->context(),
                    env()->get_shared_array_buffer_id_string())
                      .ToLocalChecked();

  if (!get_shared_array_buffer_id->IsFunction()) {
    return ValueSerializer::Delegate::GetSharedArrayBufferId(
        isolate, shared_array_buffer);
  }

  MaybeLocal<Value> id =
      get_shared_array_buffer_id.As<Function>()->Call(env()->context(),
                                                      object(),
                                                      arraysize(args),
                                                      args);

  if (id.IsEmpty()) return Nothing<uint32_t>();

  return id.ToLocalChecked()->Uint32Value(env()->context());
}

Maybe<bool> SerializerContext::WriteHostObject(Isolate* isolate,
                                               Local<Object> input) {
  MaybeLocal<Value> ret;
  Local<Value> args[1] = { input };

  Local<Value> write_host_object =
      object()->Get(env()->context(),
                    env()->write_host_object_string()).ToLocalChecked();

  if (!write_host_object->IsFunction()) {
    return ValueSerializer::Delegate::WriteHostObject(isolate, input);
  }

  ret = write_host_object.As<Function>()->Call(env()->context(),
                                               object(),
                                               arraysize(args),
                                               args);

  if (ret.IsEmpty())
    return Nothing<bool>();

  return Just(true);
}

void SerializerContext::New(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  if (!args.IsConstructCall()) {
    return THROW_ERR_CONSTRUCT_CALL_REQUIRED(
        env, "Class constructor Serializer cannot be invoked without 'new'");
  }

  new SerializerContext(env, args.This());
}

void SerializerContext::WriteHeader(const FunctionCallbackInfo<Value>& args) {
  SerializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
  ctx->serializer_.WriteHeader();
}

void SerializerContext::WriteValue(const FunctionCallbackInfo<Value>& args) {
  SerializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
  Maybe<bool> ret =
      ctx->serializer_.WriteValue(ctx->env()->context(), args[0]);

  if (ret.IsJust()) args.GetReturnValue().Set(ret.FromJust());
}

void SerializerContext::SetTreatArrayBufferViewsAsHostObjects(
    const FunctionCallbackInfo<Value>& args) {
  SerializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  bool value = args[0]->BooleanValue(ctx->env()->isolate());
  ctx->serializer_.SetTreatArrayBufferViewsAsHostObjects(value);
}

void SerializerContext::ReleaseBuffer(const FunctionCallbackInfo<Value>& args) {
  SerializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  // Note: Both ValueSerializer and this Buffer::New() variant use malloc()
  // as the underlying allocator.
  std::pair<uint8_t*, size_t> ret = ctx->serializer_.Release();
  auto buf = Buffer::New(ctx->env(),
                         reinterpret_cast<char*>(ret.first),
                         ret.second);

  if (!buf.IsEmpty()) {
    args.GetReturnValue().Set(buf.ToLocalChecked());
  }
}

void SerializerContext::TransferArrayBuffer(
    const FunctionCallbackInfo<Value>& args) {
  SerializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  Maybe<uint32_t> id = args[0]->Uint32Value(ctx->env()->context());
  if (id.IsNothing()) return;

  if (!args[1]->IsArrayBuffer())
    return node::THROW_ERR_INVALID_ARG_TYPE(
        ctx->env(), "arrayBuffer must be an ArrayBuffer");

  Local<ArrayBuffer> ab = args[1].As<ArrayBuffer>();
  ctx->serializer_.TransferArrayBuffer(id.FromJust(), ab);
  return;
}

void SerializerContext::WriteUint32(const FunctionCallbackInfo<Value>& args) {
  SerializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  Maybe<uint32_t> value = args[0]->Uint32Value(ctx->env()->context());
  if (value.IsNothing()) return;

  ctx->serializer_.WriteUint32(value.FromJust());
}

void SerializerContext::WriteUint64(const FunctionCallbackInfo<Value>& args) {
  SerializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  Maybe<uint32_t> arg0 = args[0]->Uint32Value(ctx->env()->context());
  Maybe<uint32_t> arg1 = args[1]->Uint32Value(ctx->env()->context());
  if (arg0.IsNothing() || arg1.IsNothing())
    return;

  uint64_t hi = arg0.FromJust();
  uint64_t lo = arg1.FromJust();
  ctx->serializer_.WriteUint64((hi << 32) | lo);
}

void SerializerContext::WriteDouble(const FunctionCallbackInfo<Value>& args) {
  SerializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  Maybe<double> value = args[0]->NumberValue(ctx->env()->context());
  if (value.IsNothing()) return;

  ctx->serializer_.WriteDouble(value.FromJust());
}

void SerializerContext::WriteRawBytes(const FunctionCallbackInfo<Value>& args) {
  SerializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  if (!args[0]->IsArrayBufferView()) {
    return node::THROW_ERR_INVALID_ARG_TYPE(
        ctx->env(), "source must be a TypedArray or a DataView");
  }

  ArrayBufferViewContents<char> bytes(args[0]);
  ctx->serializer_.WriteRawBytes(bytes.data(), bytes.length());
}

DeserializerContext::DeserializerContext(Environment* env,
                                         Local<Object> wrap,
                                         Local<Value> buffer)
  : BaseObject(env, wrap),
    data_(reinterpret_cast<const uint8_t*>(Buffer::Data(buffer))),
    length_(Buffer::Length(buffer)),
    deserializer_(env->isolate(), data_, length_, this) {
  object()->Set(env->context(), env->buffer_string(), buffer).Check();

  MakeWeak();
}

MaybeLocal<Object> DeserializerContext::ReadHostObject(Isolate* isolate) {
  Local<Value> read_host_object =
      object()->Get(env()->context(),
                    env()->read_host_object_string()).ToLocalChecked();

  if (!read_host_object->IsFunction()) {
    return ValueDeserializer::Delegate::ReadHostObject(isolate);
  }

  Isolate::AllowJavascriptExecutionScope allow_js(isolate);
  MaybeLocal<Value> ret =
      read_host_object.As<Function>()->Call(env()->context(),
                                            object(),
                                            0,
                                            nullptr);

  if (ret.IsEmpty())
    return MaybeLocal<Object>();

  Local<Value> return_value = ret.ToLocalChecked();
  if (!return_value->IsObject()) {
    env()->ThrowTypeError("readHostObject must return an object");
    return MaybeLocal<Object>();
  }

  return return_value.As<Object>();
}

void DeserializerContext::New(const FunctionCallbackInfo<Value>& args) {
  Environment* env = Environment::GetCurrent(args);
  if (!args.IsConstructCall()) {
    return THROW_ERR_CONSTRUCT_CALL_REQUIRED(
        env, "Class constructor Deserializer cannot be invoked without 'new'");
  }

  if (!args[0]->IsArrayBufferView()) {
    return node::THROW_ERR_INVALID_ARG_TYPE(
        env, "buffer must be a TypedArray or a DataView");
  }

  new DeserializerContext(env, args.This(), args[0]);
}

void DeserializerContext::ReadHeader(const FunctionCallbackInfo<Value>& args) {
  DeserializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  Maybe<bool> ret = ctx->deserializer_.ReadHeader(ctx->env()->context());

  if (ret.IsJust()) args.GetReturnValue().Set(ret.FromJust());
}

void DeserializerContext::ReadValue(const FunctionCallbackInfo<Value>& args) {
  DeserializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  MaybeLocal<Value> ret = ctx->deserializer_.ReadValue(ctx->env()->context());

  if (!ret.IsEmpty()) args.GetReturnValue().Set(ret.ToLocalChecked());
}

void DeserializerContext::TransferArrayBuffer(
    const FunctionCallbackInfo<Value>& args) {
  DeserializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  Maybe<uint32_t> id = args[0]->Uint32Value(ctx->env()->context());
  if (id.IsNothing()) return;

  if (args[1]->IsArrayBuffer()) {
    Local<ArrayBuffer> ab = args[1].As<ArrayBuffer>();
    ctx->deserializer_.TransferArrayBuffer(id.FromJust(), ab);
    return;
  }

  if (args[1]->IsSharedArrayBuffer()) {
    Local<SharedArrayBuffer> sab = args[1].As<SharedArrayBuffer>();
    ctx->deserializer_.TransferSharedArrayBuffer(id.FromJust(), sab);
    return;
  }

  return node::THROW_ERR_INVALID_ARG_TYPE(
      ctx->env(), "arrayBuffer must be an ArrayBuffer or SharedArrayBuffer");
}

void DeserializerContext::GetWireFormatVersion(
    const FunctionCallbackInfo<Value>& args) {
  DeserializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  args.GetReturnValue().Set(ctx->deserializer_.GetWireFormatVersion());
}

void DeserializerContext::ReadUint32(const FunctionCallbackInfo<Value>& args) {
  DeserializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  uint32_t value;
  bool ok = ctx->deserializer_.ReadUint32(&value);
  if (!ok) return ctx->env()->ThrowError("ReadUint32() failed");
  return args.GetReturnValue().Set(value);
}

void DeserializerContext::ReadUint64(const FunctionCallbackInfo<Value>& args) {
  DeserializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  uint64_t value;
  bool ok = ctx->deserializer_.ReadUint64(&value);
  if (!ok) return ctx->env()->ThrowError("ReadUint64() failed");

  uint32_t hi = static_cast<uint32_t>(value >> 32);
  uint32_t lo = static_cast<uint32_t>(value);

  Isolate* isolate = ctx->env()->isolate();

  Local<Value> ret[] = {
    Integer::NewFromUnsigned(isolate, hi),
    Integer::NewFromUnsigned(isolate, lo)
  };
  return args.GetReturnValue().Set(Array::New(isolate, ret, arraysize(ret)));
}

void DeserializerContext::ReadDouble(const FunctionCallbackInfo<Value>& args) {
  DeserializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  double value;
  bool ok = ctx->deserializer_.ReadDouble(&value);
  if (!ok) return ctx->env()->ThrowError("ReadDouble() failed");
  return args.GetReturnValue().Set(value);
}

void DeserializerContext::ReadRawBytes(
    const FunctionCallbackInfo<Value>& args) {
  DeserializerContext* ctx;
  ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());

  Maybe<int64_t> length_arg = args[0]->IntegerValue(ctx->env()->context());
  if (length_arg.IsNothing()) return;
  size_t length = length_arg.FromJust();

  const void* data;
  bool ok = ctx->deserializer_.ReadRawBytes(length, &data);
  if (!ok) return ctx->env()->ThrowError("ReadRawBytes() failed");

  const uint8_t* position = reinterpret_cast<const uint8_t*>(data);
  CHECK_GE(position, ctx->data_);
  CHECK_LE(position + length, ctx->data_ + ctx->length_);

  const uint32_t offset = static_cast<uint32_t>(position - ctx->data_);
  CHECK_EQ(ctx->data_ + offset, position);

  args.GetReturnValue().Set(offset);
}

void Initialize(Local<Object> target,
                Local<Value> unused,
                Local<Context> context,
                void* priv) {
  Environment* env = Environment::GetCurrent(context);
  Local<FunctionTemplate> ser =
      env->NewFunctionTemplate(SerializerContext::New);

  ser->InstanceTemplate()->SetInternalFieldCount(
      SerializerContext::kInternalFieldCount);
  ser->Inherit(BaseObject::GetConstructorTemplate(env));

  env->SetProtoMethod(ser, "writeHeader", SerializerContext::WriteHeader);
  env->SetProtoMethod(ser, "writeValue", SerializerContext::WriteValue);
  env->SetProtoMethod(ser, "releaseBuffer", SerializerContext::ReleaseBuffer);
  env->SetProtoMethod(ser,
                      "transferArrayBuffer",
                      SerializerContext::TransferArrayBuffer);
  env->SetProtoMethod(ser, "writeUint32", SerializerContext::WriteUint32);
  env->SetProtoMethod(ser, "writeUint64", SerializerContext::WriteUint64);
  env->SetProtoMethod(ser, "writeDouble", SerializerContext::WriteDouble);
  env->SetProtoMethod(ser, "writeRawBytes", SerializerContext::WriteRawBytes);
  env->SetProtoMethod(ser,
                      "_setTreatArrayBufferViewsAsHostObjects",
                      SerializerContext::SetTreatArrayBufferViewsAsHostObjects);

  ser->ReadOnlyPrototype();
  env->SetConstructorFunction(target, "Serializer", ser);

  Local<FunctionTemplate> des =
      env->NewFunctionTemplate(DeserializerContext::New);

  des->InstanceTemplate()->SetInternalFieldCount(
      DeserializerContext::kInternalFieldCount);
  des->Inherit(BaseObject::GetConstructorTemplate(env));

  env->SetProtoMethod(des, "readHeader", DeserializerContext::ReadHeader);
  env->SetProtoMethod(des, "readValue", DeserializerContext::ReadValue);
  env->SetProtoMethod(des,
                      "getWireFormatVersion",
                      DeserializerContext::GetWireFormatVersion);
  env->SetProtoMethod(des,
                      "transferArrayBuffer",
                      DeserializerContext::TransferArrayBuffer);
  env->SetProtoMethod(des, "readUint32", DeserializerContext::ReadUint32);
  env->SetProtoMethod(des, "readUint64", DeserializerContext::ReadUint64);
  env->SetProtoMethod(des, "readDouble", DeserializerContext::ReadDouble);
  env->SetProtoMethod(des, "_readRawBytes", DeserializerContext::ReadRawBytes);

  des->SetLength(1);
  des->ReadOnlyPrototype();
  env->SetConstructorFunction(target, "Deserializer", des);
}

void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
  registry->Register(SerializerContext::New);

  registry->Register(SerializerContext::WriteHeader);
  registry->Register(SerializerContext::WriteValue);
  registry->Register(SerializerContext::ReleaseBuffer);
  registry->Register(SerializerContext::TransferArrayBuffer);
  registry->Register(SerializerContext::WriteUint32);
  registry->Register(SerializerContext::WriteUint64);
  registry->Register(SerializerContext::WriteDouble);
  registry->Register(SerializerContext::WriteRawBytes);
  registry->Register(SerializerContext::SetTreatArrayBufferViewsAsHostObjects);

  registry->Register(DeserializerContext::New);
  registry->Register(DeserializerContext::ReadHeader);
  registry->Register(DeserializerContext::ReadValue);
  registry->Register(DeserializerContext::GetWireFormatVersion);
  registry->Register(DeserializerContext::TransferArrayBuffer);
  registry->Register(DeserializerContext::ReadUint32);
  registry->Register(DeserializerContext::ReadUint64);
  registry->Register(DeserializerContext::ReadDouble);
  registry->Register(DeserializerContext::ReadRawBytes);
}

}  // namespace serdes
}  // namespace node

NODE_MODULE_CONTEXT_AWARE_INTERNAL(serdes, node::serdes::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(serdes, node::serdes::RegisterExternalReferences)
