// Copyright 2017 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.

#include "third_party/blink/renderer/modules/locks/lock.h"

#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/modules/locks/lock_manager.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"

namespace blink {

namespace {
const char* kLockModeNameExclusive = "exclusive";
const char* kLockModeNameShared = "shared";
}  // namespace

class Lock::ThenFunction final : public ScriptFunction {
 public:
  enum ResolveType {
    Fulfilled,
    Rejected,
  };

  static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
                                                Lock* lock,
                                                ResolveType type) {
    ThenFunction* self =
        MakeGarbageCollected<ThenFunction>(script_state, lock, type);
    return self->BindToV8Function();
  }

  ThenFunction(ScriptState* script_state, Lock* lock, ResolveType type)
      : ScriptFunction(script_state), lock_(lock), resolve_type_(type) {}

  void Trace(blink::Visitor* visitor) override {
    visitor->Trace(lock_);
    ScriptFunction::Trace(visitor);
  }

 private:
  ScriptValue Call(ScriptValue value) override {
    DCHECK(lock_);
    DCHECK(resolve_type_ == Fulfilled || resolve_type_ == Rejected);
    lock_->ReleaseIfHeld();
    if (resolve_type_ == Fulfilled)
      lock_->resolver_->Resolve(value);
    else
      lock_->resolver_->Reject(value);
    lock_ = nullptr;
    return value;
  }

  Member<Lock> lock_;
  ResolveType resolve_type_;
};

// static
Lock* Lock::Create(ScriptState* script_state,
                   const String& name,
                   mojom::blink::LockMode mode,
                   mojom::blink::LockHandleAssociatedPtr handle,
                   LockManager* manager) {
  return MakeGarbageCollected<Lock>(script_state, name, mode, std::move(handle),
                                    manager);
}

Lock::Lock(ScriptState* script_state,
           const String& name,
           mojom::blink::LockMode mode,
           mojom::blink::LockHandleAssociatedPtr handle,
           LockManager* manager)
    : ContextLifecycleObserver(ExecutionContext::From(script_state)),
      name_(name),
      mode_(mode),
      handle_(std::move(handle)),
      manager_(manager) {
  handle_.set_connection_error_handler(
      WTF::Bind(&Lock::OnConnectionError, WrapWeakPersistent(this)));
}

Lock::~Lock() = default;

String Lock::mode() const {
  return ModeToString(mode_);
}

void Lock::HoldUntil(ScriptPromise promise, ScriptPromiseResolver* resolver) {
  DCHECK(handle_.is_bound());
  DCHECK(!resolver_);

  ScriptState* script_state = resolver->GetScriptState();
  resolver_ = resolver;
  promise.Then(
      ThenFunction::CreateFunction(script_state, this, ThenFunction::Fulfilled),
      ThenFunction::CreateFunction(script_state, this, ThenFunction::Rejected));
}

// static
mojom::blink::LockMode Lock::StringToMode(const String& string) {
  if (string == kLockModeNameShared)
    return mojom::blink::LockMode::SHARED;
  if (string == kLockModeNameExclusive)
    return mojom::blink::LockMode::EXCLUSIVE;
  NOTREACHED();
  return mojom::blink::LockMode::SHARED;
}

// static
String Lock::ModeToString(mojom::blink::LockMode mode) {
  switch (mode) {
    case mojom::blink::LockMode::SHARED:
      return kLockModeNameShared;
    case mojom::blink::LockMode::EXCLUSIVE:
      return kLockModeNameExclusive;
  }
  NOTREACHED();
  return g_empty_string;
}

void Lock::ContextDestroyed(ExecutionContext* context) {
  ReleaseIfHeld();
}

void Lock::Trace(blink::Visitor* visitor) {
  ContextLifecycleObserver::Trace(visitor);
  ScriptWrappable::Trace(visitor);
  visitor->Trace(resolver_);
  visitor->Trace(manager_);
}

void Lock::ReleaseIfHeld() {
  if (handle_) {
    // Drop the mojo pipe; this releases the lock on the back end.
    handle_.reset();

    // Let the lock manager know that this instance can be collected.
    manager_->OnLockReleased(this);
  }
}

void Lock::OnConnectionError() {
  resolver_->Reject(DOMException::Create(
      DOMExceptionCode::kAbortError,
      "Lock broken by another request with the 'steal' option."));
}

}  // namespace blink
