// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Implementation of functions that are shared between ReadableStream and
// WritableStream.

#include "third_party/blink/renderer/core/streams/miscellaneous_operations.h"

#include <math.h>

#include "base/optional.h"
#include "third_party/blink/renderer/core/streams/stream_algorithms.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/heap/visitor.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"

namespace blink {

namespace {

// ResolveMethod implements part of CreateAlgorithmFromUnderlyingMethod and
// CallOrNoop1.
v8::MaybeLocal<v8::Value> ResolveMethod(ScriptState* script_state,
                                        v8::Local<v8::Object> object,
                                        const char* method_name,
                                        const char* name_for_error,
                                        ExceptionState& exception_state) {
  auto* isolate = script_state->GetIsolate();
  v8::TryCatch try_catch(isolate);

  // Algorithm steps from CreateAlgorithmFromUnderlyingMethod in the standard.
  // https://streams.spec.whatwg.org/#create-algorithm-from-underlying-method
  // 5. Let method be ? GetV(underlyingObject, methodName).
  auto method_maybe = object->Get(script_state->GetContext(),
                                  V8AtomicString(isolate, method_name));
  v8::Local<v8::Value> method;
  if (!method_maybe.ToLocal(&method)) {
    exception_state.RethrowV8Exception(try_catch.Exception());
    return v8::MaybeLocal<v8::Value>();
  }

  // 6. If method is not undefined,
  //    a. If ! IsCallable(method) is false, throw a TypeError exception.
  if (!method->IsFunction() && !method->IsUndefined()) {
    exception_state.ThrowTypeError(String(name_for_error) +
                                   " must be a function or undefined");
    return v8::MaybeLocal<v8::Value>();
  }

  return method;
}

// PromiseRejectInternal() implements Promise.reject(_r_) from the ECMASCRIPT
// standard, https://tc39.github.io/ecma262/#sec-promise.reject.
// The |recursion_depth| argument is used to prevent infinite recursion in the
// case that we can't create a promise.
v8::Local<v8::Promise> PromiseRejectInternal(ScriptState* script_state,
                                             v8::Local<v8::Value> value,
                                             int recursion_depth) {
  auto context = script_state->GetContext();
  v8::TryCatch trycatch(script_state->GetIsolate());
  // TODO(ricea): Can this fail for reasons other than memory exhaustion? Can we
  // recover if it does?
  auto resolver = v8::Promise::Resolver::New(context).ToLocalChecked();
  if (resolver->Reject(context, value).IsNothing()) {
    // Assume that the exception can be successfully used to create a Promise.
    // TODO(ricea): Can the body of this if statement actually be reached?
    if (recursion_depth >= 2) {
      LOG(FATAL) << "Recursion depth exceeded in PromiseRejectInternal";
    }
    return PromiseRejectInternal(script_state, trycatch.Exception(),
                                 recursion_depth + 1);
  }
  return resolver->GetPromise();
}

class DefaultSizeAlgorithm final : public StrategySizeAlgorithm {
 public:
  base::Optional<double> Run(ScriptState*,
                             v8::Local<v8::Value>,
                             ExceptionState&) override {
    return 1;
  }
};

class JavaScriptSizeAlgorithm final : public StrategySizeAlgorithm {
 public:
  JavaScriptSizeAlgorithm(v8::Isolate* isolate, v8::Local<v8::Function> size)
      : function_(isolate, size) {}

  base::Optional<double> Run(ScriptState* script_state,
                             v8::Local<v8::Value> chunk,
                             ExceptionState& exception_state) override {
    auto* isolate = script_state->GetIsolate();
    auto context = script_state->GetContext();
    v8::TryCatch trycatch(isolate);
    v8::Local<v8::Value> argv[] = {chunk};

    // https://streams.spec.whatwg.org/#make-size-algorithm-from-size-function
    // 3.a. Return ? Call(size, undefined, « chunk »).
    v8::MaybeLocal<v8::Value> result_maybe = function_.NewLocal(isolate)->Call(
        context, v8::Undefined(isolate), 1, argv);
    v8::Local<v8::Value> result;
    if (!result_maybe.ToLocal(&result)) {
      exception_state.RethrowV8Exception(trycatch.Exception());
      return base::nullopt;
    }

    // This conversion to double comes from the EnqueueValueWithSize
    // operation: https://streams.spec.whatwg.org/#enqueue-value-with-size
    // 2. Let size be ? ToNumber(size).
    v8::MaybeLocal<v8::Number> number_maybe = result->ToNumber(context);
    v8::Local<v8::Number> number;
    if (!number_maybe.ToLocal(&number)) {
      exception_state.RethrowV8Exception(trycatch.Exception());
      return base::nullopt;
    }
    return number->Value();
  }

  void Trace(Visitor* visitor) override {
    visitor->Trace(function_);
    StrategySizeAlgorithm::Trace(visitor);
  }

 private:
  TraceWrapperV8Reference<v8::Function> function_;
};

class TrivialStreamAlgorithm final : public StreamAlgorithm {
 public:
  v8::Local<v8::Promise> Run(ScriptState* script_state,
                             int argc,
                             v8::Local<v8::Value> argv[]) override {
    return PromiseResolveWithUndefined(script_state);
  }
};

class JavaScriptStreamAlgorithmWithoutExtraArg final : public StreamAlgorithm {
 public:
  JavaScriptStreamAlgorithmWithoutExtraArg(v8::Isolate* isolate,
                                           v8::Local<v8::Function> method,
                                           v8::Local<v8::Object> recv)
      : recv_(isolate, recv), method_(isolate, method) {}

  // |argc| is equivalent to the "algoArgCount" argument to
  // CreateAlgorithmFromUnderlyingMethod() in the standard, but it is
  // determined when the algorithm is called rather than when the algorithm is
  // created.
  v8::Local<v8::Promise> Run(ScriptState* script_state,
                             int argc,
                             v8::Local<v8::Value> argv[]) override {
    // This method technically supports any number of arguments, but we only
    // call it with 0 or 1 in practice.
    DCHECK_GE(argc, 0);
    auto* isolate = script_state->GetIsolate();
    // https://streams.spec.whatwg.org/#create-algorithm-from-underlying-method
    // 6.b.i. Return ! PromiseCall(method, underlyingObject, extraArgs).
    // In this class extraArgs is always empty, but there may be other arguments
    // supplied to the method.
    return PromiseCall(script_state, method_.NewLocal(isolate),
                       recv_.NewLocal(isolate), argc, argv);
  }

  void Trace(Visitor* visitor) override {
    visitor->Trace(recv_);
    visitor->Trace(method_);
    StreamAlgorithm::Trace(visitor);
  }

 private:
  TraceWrapperV8Reference<v8::Object> recv_;
  TraceWrapperV8Reference<v8::Function> method_;
};

class JavaScriptStreamAlgorithmWithExtraArg final : public StreamAlgorithm {
 public:
  JavaScriptStreamAlgorithmWithExtraArg(v8::Isolate* isolate,
                                        v8::Local<v8::Function> method,
                                        v8::Local<v8::Value> extra_arg,
                                        v8::Local<v8::Object> recv)
      : recv_(isolate, recv),
        method_(isolate, method),
        extra_arg_(isolate, extra_arg) {}

  // |argc| is equivalent to the "algoArgCount" argument to
  // CreateAlgorithmFromUnderlyingMethod() in the standard,
  v8::Local<v8::Promise> Run(ScriptState* script_state,
                             int argc,
                             v8::Local<v8::Value> argv[]) override {
    DCHECK_GE(argc, 0);
    DCHECK_LE(argc, 1);
    auto* isolate = script_state->GetIsolate();
    // https://streams.spec.whatwg.org/#create-algorithm-from-underlying-method
    // 6.c.
    //      i. Let fullArgs be a List consisting of arg followed by the
    //         elements of extraArgs in order.
    v8::Local<v8::Value> full_argv[2];
    if (argc != 0) {
      full_argv[0] = argv[0];
    }
    full_argv[argc] = extra_arg_.NewLocal(isolate);
    int full_argc = argc + 1;

    //     ii. Return ! PromiseCall(method, underlyingObject, fullArgs).
    return PromiseCall(script_state, method_.NewLocal(isolate),
                       recv_.NewLocal(isolate), full_argc, full_argv);
  }

  void Trace(Visitor* visitor) override {
    visitor->Trace(recv_);
    visitor->Trace(method_);
    visitor->Trace(extra_arg_);
    StreamAlgorithm::Trace(visitor);
  }

 private:
  TraceWrapperV8Reference<v8::Object> recv_;
  TraceWrapperV8Reference<v8::Function> method_;
  TraceWrapperV8Reference<v8::Value> extra_arg_;
};

class JavaScriptStreamStartAlgorithm : public StreamStartAlgorithm {
 public:
  JavaScriptStreamStartAlgorithm(v8::Isolate* isolate,
                                 v8::Local<v8::Object> recv,
                                 const char* method_name_for_error,
                                 v8::Local<v8::Value> controller)
      : recv_(isolate, recv),
        method_name_for_error_(method_name_for_error),
        controller_(isolate, controller) {}

  v8::MaybeLocal<v8::Promise> Run(ScriptState* script_state,
                                  ExceptionState& exception_state) override {
    auto* isolate = script_state->GetIsolate();
    // https://streams.spec.whatwg.org/#set-up-writable-stream-default-controller-from-underlying-sink
    // 3. Let startAlgorithm be the following steps:
    //    a. Return ? InvokeOrNoop(underlyingSink, "start", « controller »).
    auto value_maybe = CallOrNoop1(
        script_state, recv_.NewLocal(isolate), "start", method_name_for_error_,
        controller_.NewLocal(isolate), exception_state);
    if (exception_state.HadException()) {
      return v8::MaybeLocal<v8::Promise>();
    }
    v8::Local<v8::Value> value;
    if (!value_maybe.ToLocal(&value)) {
      exception_state.ThrowTypeError("internal error");
      return v8::MaybeLocal<v8::Promise>();
    }
    return PromiseResolve(script_state, value);
  }

  void Trace(Visitor* visitor) override {
    visitor->Trace(recv_);
    visitor->Trace(controller_);
    StreamStartAlgorithm::Trace(visitor);
  }

 private:
  TraceWrapperV8Reference<v8::Object> recv_;
  const char* const method_name_for_error_;
  TraceWrapperV8Reference<v8::Value> controller_;
};

}  // namespace

// TODO(ricea): For optimal performance, method_name should be cached as an
// atomic v8::String. It's not clear who should own the cache.
CORE_EXPORT StreamAlgorithm* CreateAlgorithmFromUnderlyingMethod(
    ScriptState* script_state,
    v8::Local<v8::Object> underlying_object,
    const char* method_name,
    const char* method_name_for_error,
    v8::MaybeLocal<v8::Value> extra_arg,
    ExceptionState& exception_state) {
  // https://streams.spec.whatwg.org/#create-algorithm-from-underlying-method
  // 5. Let method be ? GetV(underlyingObject, methodName).
  // 6. If method is not undefined,
  //    a. If ! IsCallable(method) is false, throw a TypeError exception.
  v8::MaybeLocal<v8::Value> method_maybe =
      ResolveMethod(script_state, underlying_object, method_name,
                    method_name_for_error, exception_state);
  v8::Local<v8::Value> method;
  if (!method_maybe.ToLocal(&method)) {
    DCHECK(exception_state.HadException());
    return nullptr;
  }

  if (method->IsUndefined()) {
    // 7. Return an algorithm which returns a promise resolved with undefined.
    return MakeGarbageCollected<TrivialStreamAlgorithm>();
  }
  DCHECK(method->IsFunction());

  auto* isolate = script_state->GetIsolate();

  // The standard switches on the number of arguments to be passed to the
  // algorithm, but this implementation doesn't care about that. Instead we
  // switch on whether or not there is an extraArg, as that decides whether or
  // not we need to reconstruct the argument list at runtime.
  v8::Local<v8::Value> extra_arg_local;
  if (!extra_arg.ToLocal(&extra_arg_local)) {
    return MakeGarbageCollected<JavaScriptStreamAlgorithmWithoutExtraArg>(
        isolate, method.As<v8::Function>(), underlying_object);
  }

  return MakeGarbageCollected<JavaScriptStreamAlgorithmWithExtraArg>(
      isolate, method.As<v8::Function>(), extra_arg_local, underlying_object);
}

CORE_EXPORT StreamStartAlgorithm* CreateStartAlgorithm(
    ScriptState* script_state,
    v8::Local<v8::Object> underlying_object,
    const char* method_name_for_error,
    v8::Local<v8::Value> controller) {
  return MakeGarbageCollected<JavaScriptStreamStartAlgorithm>(
      script_state->GetIsolate(), underlying_object, method_name_for_error,
      controller);
}

CORE_EXPORT v8::MaybeLocal<v8::Value> CallOrNoop1(
    ScriptState* script_state,
    v8::Local<v8::Object> object,
    const char* method_name,
    const char* name_for_error,
    v8::Local<v8::Value> arg0,
    ExceptionState& exception_state) {
  // https://streams.spec.whatwg.org/#invoke-or-noop
  // 4. Let method be ? GetV(O, P).
  v8::MaybeLocal<v8::Value> method_maybe = ResolveMethod(
      script_state, object, method_name, name_for_error, exception_state);
  v8::Local<v8::Value> method;
  if (!method_maybe.ToLocal(&method)) {
    DCHECK(exception_state.HadException());
    return v8::MaybeLocal<v8::Value>();
  }

  // 5. If method is undefined, return undefined.
  if (method->IsUndefined()) {
    return v8::Undefined(script_state->GetIsolate());
  }
  DCHECK(method->IsFunction());

  // 6. Return ? Call(method, O, args).
  return method.As<v8::Function>()->Call(script_state->GetContext(), object, 1,
                                         &arg0);
}

CORE_EXPORT v8::Local<v8::Promise> PromiseCall(ScriptState* script_state,
                                               v8::Local<v8::Function> method,
                                               v8::Local<v8::Object> recv,
                                               int argc,
                                               v8::Local<v8::Value> argv[]) {
  DCHECK_GE(argc, 0);
  v8::TryCatch trycatch(script_state->GetIsolate());

  // https://streams.spec.whatwg.org/#promise-call
  // 4. Let returnValue be Call(F, V, args).
  v8::MaybeLocal<v8::Value> result_maybe =
      method->Call(script_state->GetContext(), recv, argc, argv);

  v8::Local<v8::Value> result;
  // 5. If returnValue is an abrupt completion, return a promise rejected with
  //    returnValue.[[Value]].
  if (!result_maybe.ToLocal(&result)) {
    return PromiseReject(script_state, trycatch.Exception());
  }

  // 6. Otherwise, return a promise resolved with returnValue.[[Value]].
  return PromiseResolve(script_state, result);
}

CORE_EXPORT double ValidateAndNormalizeHighWaterMark(
    double high_water_mark,
    ExceptionState& exception_state) {
  // https://streams.spec.whatwg.org/#validate-and-normalize-high-water-mark
  // 2. If highWaterMark is NaN or highWaterMark < 0, throw a RangeError
  //    exception.
  if (isnan(high_water_mark) || high_water_mark < 0) {
    exception_state.ThrowRangeError(
        "A queuing strategy's highWaterMark property must be a nonnegative, "
        "non-NaN number");
    return 0;
  }

  // 3. Return highWaterMark.
  return high_water_mark;
}

CORE_EXPORT StrategySizeAlgorithm* MakeSizeAlgorithmFromSizeFunction(
    ScriptState* script_state,
    v8::Local<v8::Value> size,
    ExceptionState& exception_state) {
  // 1. If size is undefined, return an algorithm that returns 1.
  if (size->IsUndefined()) {
    return MakeGarbageCollected<DefaultSizeAlgorithm>();
  }

  // 2. If ! IsCallable(size) is false, throw a TypeError exception.
  if (!size->IsFunction()) {
    exception_state.ThrowTypeError(
        "A queuing strategy's size property must be a function");
    return nullptr;
  }

  // 3. Return an algorithm that performs the following steps, taking a chunk
  // argument:
  //    a. Return ? Call(size, undefined, « chunk »).
  return MakeGarbageCollected<JavaScriptSizeAlgorithm>(
      script_state->GetIsolate(), size.As<v8::Function>());
}

// PromiseResolve implements Promise.resolve(_x_) from the ECMASCRIPT standard,
// https://tc39.github.io/ecma262/#sec-promise.resolve, except that the
// Get(_x_, "constructor") step is skipped.
CORE_EXPORT v8::Local<v8::Promise> PromiseResolve(ScriptState* script_state,
                                                  v8::Local<v8::Value> value) {
  if (value->IsPromise()) {
    return value.As<v8::Promise>();
  }
  auto context = script_state->GetContext();
  v8::TryCatch trycatch(script_state->GetIsolate());
  // TODO(ricea): Can this fail for reasons other than memory exhaustion? Can we
  // recover if it does?
  auto resolver = v8::Promise::Resolver::New(context).ToLocalChecked();
  if (resolver->Resolve(context, value).IsNothing()) {
    // TODO(ricea): Is this actually reachable?
    return PromiseReject(script_state, trycatch.Exception());
  }
  return resolver->GetPromise();
}

CORE_EXPORT v8::Local<v8::Promise> PromiseResolveWithUndefined(
    ScriptState* script_state) {
  return PromiseResolve(script_state,
                        v8::Undefined(script_state->GetIsolate()));
}

CORE_EXPORT v8::Local<v8::Promise> PromiseReject(ScriptState* script_state,
                                                 v8::Local<v8::Value> value) {
  return PromiseRejectInternal(script_state, value, 0);
}

}  // namespace blink
