/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "bindings/core/v8/ScriptPromise.h"

#include "bindings/core/v8/ExceptionMessages.h"
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/ToV8.h"
#include "bindings/core/v8/V8ThrowException.h"
#include "core/dom/DOMException.h"
#include "core/inspector/InstanceCounters.h"
#include <v8.h>

namespace blink {

namespace {

class PromiseAllHandler final
    : public GarbageCollectedFinalized<PromiseAllHandler> {
  WTF_MAKE_NONCOPYABLE(PromiseAllHandler);

 public:
  static ScriptPromise all(ScriptState* scriptState,
                           const Vector<ScriptPromise>& promises) {
    if (promises.isEmpty())
      return ScriptPromise::cast(scriptState,
                                 v8::Array::New(scriptState->isolate()));
    return (new PromiseAllHandler(scriptState, promises))->m_resolver.promise();
  }

  DEFINE_INLINE_VIRTUAL_TRACE() {}

 private:
  class AdapterFunction : public ScriptFunction {
   public:
    enum ResolveType {
      Fulfilled,
      Rejected,
    };

    static v8::Local<v8::Function> create(ScriptState* scriptState,
                                          ResolveType resolveType,
                                          size_t index,
                                          PromiseAllHandler* handler) {
      AdapterFunction* self =
          new AdapterFunction(scriptState, resolveType, index, handler);
      return self->bindToV8Function();
    }

    DEFINE_INLINE_VIRTUAL_TRACE() {
      visitor->trace(m_handler);
      ScriptFunction::trace(visitor);
    }

   private:
    AdapterFunction(ScriptState* scriptState,
                    ResolveType resolveType,
                    size_t index,
                    PromiseAllHandler* handler)
        : ScriptFunction(scriptState),
          m_resolveType(resolveType),
          m_index(index),
          m_handler(handler) {}

    ScriptValue call(ScriptValue value) override {
      if (m_resolveType == Fulfilled)
        m_handler->onFulfilled(m_index, value);
      else
        m_handler->onRejected(value);
      // This return value is never used.
      return ScriptValue();
    }

    const ResolveType m_resolveType;
    const size_t m_index;
    Member<PromiseAllHandler> m_handler;
  };

  PromiseAllHandler(ScriptState* scriptState, Vector<ScriptPromise> promises)
      : m_numberOfPendingPromises(promises.size()), m_resolver(scriptState) {
    ASSERT(!promises.isEmpty());
    m_values.resize(promises.size());
    for (size_t i = 0; i < promises.size(); ++i)
      promises[i].then(createFulfillFunction(scriptState, i),
                       createRejectFunction(scriptState));
  }

  v8::Local<v8::Function> createFulfillFunction(ScriptState* scriptState,
                                                size_t index) {
    return AdapterFunction::create(scriptState, AdapterFunction::Fulfilled,
                                   index, this);
  }

  v8::Local<v8::Function> createRejectFunction(ScriptState* scriptState) {
    return AdapterFunction::create(scriptState, AdapterFunction::Rejected, 0,
                                   this);
  }

  void onFulfilled(size_t index, const ScriptValue& value) {
    if (m_isSettled)
      return;

    ASSERT(index < m_values.size());
    m_values[index] = value;
    if (--m_numberOfPendingPromises > 0)
      return;

    v8::Local<v8::Array> values =
        v8::Array::New(value.isolate(), m_values.size());
    for (size_t i = 0; i < m_values.size(); ++i) {
      if (!v8CallBoolean(values->CreateDataProperty(value.context(), i,
                                                    m_values[i].v8Value())))
        return;
    }

    markPromiseSettled();
    m_resolver.resolve(values);
  }

  void onRejected(const ScriptValue& value) {
    if (m_isSettled)
      return;
    markPromiseSettled();
    m_resolver.reject(value.v8Value());
  }

  void markPromiseSettled() {
    ASSERT(!m_isSettled);
    m_isSettled = true;
    m_values.clear();
  }

  size_t m_numberOfPendingPromises;
  ScriptPromise::InternalResolver m_resolver;
  bool m_isSettled = false;

  // This is cleared when owners of this handler, that is, given promises are
  // settled.
  Vector<ScriptValue> m_values;
};

}  // namespace

ScriptPromise::InternalResolver::InternalResolver(ScriptState* scriptState)
    : m_resolver(scriptState,
                 v8::Promise::Resolver::New(scriptState->context())) {}

v8::Local<v8::Promise> ScriptPromise::InternalResolver::v8Promise() const {
  if (m_resolver.isEmpty())
    return v8::Local<v8::Promise>();
  return m_resolver.v8Value().As<v8::Promise::Resolver>()->GetPromise();
}

ScriptPromise ScriptPromise::InternalResolver::promise() const {
  if (m_resolver.isEmpty())
    return ScriptPromise();
  return ScriptPromise(m_resolver.getScriptState(), v8Promise());
}

void ScriptPromise::InternalResolver::resolve(v8::Local<v8::Value> value) {
  if (m_resolver.isEmpty())
    return;
  m_resolver.v8Value().As<v8::Promise::Resolver>()->Resolve(
      m_resolver.context(), value);
  clear();
}

void ScriptPromise::InternalResolver::reject(v8::Local<v8::Value> value) {
  if (m_resolver.isEmpty())
    return;
  m_resolver.v8Value().As<v8::Promise::Resolver>()->Reject(m_resolver.context(),
                                                           value);
  clear();
}

ScriptPromise::ScriptPromise() {
  increaseInstanceCount();
}

ScriptPromise::ScriptPromise(ScriptState* scriptState,
                             v8::Local<v8::Value> value)
    : m_scriptState(scriptState) {
  increaseInstanceCount();

  if (value.IsEmpty())
    return;

  if (!value->IsPromise()) {
    m_promise = ScriptValue(scriptState, v8::Local<v8::Value>());
    V8ThrowException::throwTypeError(scriptState->isolate(),
                                     "the given value is not a Promise");
    return;
  }
  m_promise = ScriptValue(scriptState, value);
}

ScriptPromise::ScriptPromise(const ScriptPromise& other) {
  increaseInstanceCount();

  this->m_scriptState = other.m_scriptState;
  this->m_promise = other.m_promise;
}

ScriptPromise::~ScriptPromise() {
  decreaseInstanceCount();
}

ScriptPromise ScriptPromise::then(v8::Local<v8::Function> onFulfilled,
                                  v8::Local<v8::Function> onRejected) {
  if (m_promise.isEmpty())
    return ScriptPromise();

  v8::Local<v8::Object> promise = m_promise.v8Value().As<v8::Object>();

  ASSERT(promise->IsPromise());
  // Return this Promise if no handlers are given.
  // In fact it is not the exact bahavior of Promise.prototype.then
  // but that is not a problem in this case.
  v8::Local<v8::Promise> resultPromise = promise.As<v8::Promise>();
  if (!onFulfilled.IsEmpty()) {
    if (!resultPromise->Then(m_scriptState->context(), onFulfilled)
             .ToLocal(&resultPromise))
      return ScriptPromise();
  }
  if (!onRejected.IsEmpty()) {
    if (!resultPromise->Catch(m_scriptState->context(), onRejected)
             .ToLocal(&resultPromise))
      return ScriptPromise();
  }

  return ScriptPromise(m_scriptState.get(), resultPromise);
}

ScriptPromise ScriptPromise::castUndefined(ScriptState* scriptState) {
  return ScriptPromise::cast(scriptState,
                             v8::Undefined(scriptState->isolate()));
}

ScriptPromise ScriptPromise::cast(ScriptState* scriptState,
                                  const ScriptValue& value) {
  return ScriptPromise::cast(scriptState, value.v8Value());
}

ScriptPromise ScriptPromise::cast(ScriptState* scriptState,
                                  v8::Local<v8::Value> value) {
  if (value.IsEmpty())
    return ScriptPromise();
  if (value->IsPromise()) {
    return ScriptPromise(scriptState, value);
  }
  InternalResolver resolver(scriptState);
  ScriptPromise promise = resolver.promise();
  resolver.resolve(value);
  return promise;
}

ScriptPromise ScriptPromise::reject(ScriptState* scriptState,
                                    const ScriptValue& value) {
  return ScriptPromise::reject(scriptState, value.v8Value());
}

ScriptPromise ScriptPromise::reject(ScriptState* scriptState,
                                    v8::Local<v8::Value> value) {
  if (value.IsEmpty())
    return ScriptPromise();
  InternalResolver resolver(scriptState);
  ScriptPromise promise = resolver.promise();
  resolver.reject(value);
  return promise;
}

ScriptPromise ScriptPromise::rejectWithDOMException(ScriptState* scriptState,
                                                    DOMException* exception) {
  ASSERT(scriptState->isolate()->InContext());
  return reject(scriptState, toV8(exception, scriptState->context()->Global(),
                                  scriptState->isolate()));
}

v8::Local<v8::Promise> ScriptPromise::rejectRaw(ScriptState* scriptState,
                                                v8::Local<v8::Value> value) {
  if (value.IsEmpty())
    return v8::Local<v8::Promise>();
  v8::Local<v8::Promise::Resolver> resolver;
  if (!v8::Promise::Resolver::New(scriptState->context()).ToLocal(&resolver))
    return v8::Local<v8::Promise>();
  v8::Local<v8::Promise> promise = resolver->GetPromise();
  resolver->Reject(scriptState->context(), value);
  return promise;
}

ScriptPromise ScriptPromise::all(ScriptState* scriptState,
                                 const Vector<ScriptPromise>& promises) {
  return PromiseAllHandler::all(scriptState, promises);
}

void ScriptPromise::increaseInstanceCount() {
  InstanceCounters::incrementCounter(InstanceCounters::ScriptPromiseCounter);
}

void ScriptPromise::decreaseInstanceCount() {
  InstanceCounters::decrementCounter(InstanceCounters::ScriptPromiseCounter);
}

}  // namespace blink
