// Copyright 2014 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 "components/password_manager/content/renderer/credential_manager_client.h"

#include <stddef.h>

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "components/password_manager/core/common/credential_manager_types.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/platform/WebCredential.h"
#include "third_party/WebKit/public/platform/WebCredentialManagerError.h"
#include "third_party/WebKit/public/platform/WebFederatedCredential.h"
#include "third_party/WebKit/public/platform/WebPasswordCredential.h"
#include "third_party/WebKit/public/web/WebView.h"

namespace password_manager {

namespace {

void WebCredentialToCredentialInfo(const blink::WebCredential& credential,
                                   CredentialInfo* out) {
  out->id = credential.Id().Utf16();
  out->name = credential.GetName().Utf16();
  out->icon = credential.GetIconURL();
  if (credential.IsPasswordCredential()) {
    out->type = CredentialType::CREDENTIAL_TYPE_PASSWORD;
    out->password = static_cast<const blink::WebPasswordCredential&>(credential)
                        .Password()
                        .Utf16();
  } else {
    DCHECK(credential.IsFederatedCredential());
    out->type = CredentialType::CREDENTIAL_TYPE_FEDERATED;
    out->federation =
        static_cast<const blink::WebFederatedCredential&>(credential)
            .Provider();
  }
}

std::unique_ptr<blink::WebCredential> CredentialInfoToWebCredential(
    const CredentialInfo& info) {
  switch (info.type) {
    case CredentialType::CREDENTIAL_TYPE_FEDERATED:
      return base::MakeUnique<blink::WebFederatedCredential>(
          blink::WebString::FromUTF16(info.id), info.federation,
          blink::WebString::FromUTF16(info.name), info.icon);
    case CredentialType::CREDENTIAL_TYPE_PASSWORD:
      return base::MakeUnique<blink::WebPasswordCredential>(
          blink::WebString::FromUTF16(info.id),
          blink::WebString::FromUTF16(info.password),
          blink::WebString::FromUTF16(info.name), info.icon);
    case CredentialType::CREDENTIAL_TYPE_EMPTY:
      return nullptr;
  }

  NOTREACHED();
  return nullptr;
}

CredentialMediationRequirement GetCredentialMediationRequirementFromBlink(
    blink::WebCredentialMediationRequirement mediation) {
  switch (mediation) {
    case blink::WebCredentialMediationRequirement::kSilent:
      return CredentialMediationRequirement::kSilent;
    case blink::WebCredentialMediationRequirement::kOptional:
      return CredentialMediationRequirement::kOptional;
    case blink::WebCredentialMediationRequirement::kRequired:
      return CredentialMediationRequirement::kRequired;
  }

  NOTREACHED();
  return CredentialMediationRequirement::kOptional;
}

blink::WebCredentialManagerError GetWebCredentialManagerErrorFromMojo(
    mojom::CredentialManagerError error) {
  switch (error) {
    case mojom::CredentialManagerError::DISABLED:
      return blink::WebCredentialManagerError::
          kWebCredentialManagerDisabledError;
    case mojom::CredentialManagerError::PENDINGREQUEST:
      return blink::WebCredentialManagerError::
          kWebCredentialManagerPendingRequestError;
    case mojom::CredentialManagerError::PASSWORDSTOREUNAVAILABLE:
      return blink::WebCredentialManagerError::
          kWebCredentialManagerPasswordStoreUnavailableError;
    case mojom::CredentialManagerError::UNKNOWN:
      return blink::WebCredentialManagerError::
          kWebCredentialManagerUnknownError;
    case mojom::CredentialManagerError::SUCCESS:
      NOTREACHED();
      break;
  }

  NOTREACHED();
  return blink::WebCredentialManagerError::kWebCredentialManagerUnknownError;
}

// Takes ownership of blink::WebCredentialManagerClient::NotificationCallbacks
// pointer. When the wrapper is destroyed, if |callbacks| is still alive
// its onError() will get called.
class NotificationCallbacksWrapper {
 public:
  explicit NotificationCallbacksWrapper(
      blink::WebCredentialManagerClient::NotificationCallbacks* callbacks);

  ~NotificationCallbacksWrapper();

  void NotifySuccess();

 private:
  std::unique_ptr<blink::WebCredentialManagerClient::NotificationCallbacks>
      callbacks_;

  DISALLOW_COPY_AND_ASSIGN(NotificationCallbacksWrapper);
};

NotificationCallbacksWrapper::NotificationCallbacksWrapper(
    blink::WebCredentialManagerClient::NotificationCallbacks* callbacks)
    : callbacks_(callbacks) {}

NotificationCallbacksWrapper::~NotificationCallbacksWrapper() {
  if (callbacks_)
    callbacks_->OnError(blink::kWebCredentialManagerUnknownError);
}

void NotificationCallbacksWrapper::NotifySuccess() {
  // Call onSuccess() and reset callbacks to avoid calling onError() in
  // destructor.
  if (callbacks_) {
    callbacks_->OnSuccess();
    callbacks_.reset();
  }
}

// Takes ownership of blink::WebCredentialManagerClient::RequestCallbacks
// pointer. When the wrapper is destroied, if |callbacks| is still alive
// its onError() will get called.
class RequestCallbacksWrapper {
 public:
  explicit RequestCallbacksWrapper(
      blink::WebCredentialManagerClient::RequestCallbacks* callbacks);

  ~RequestCallbacksWrapper();

  void NotifySuccess(const CredentialInfo& info);

  void NotifyError(mojom::CredentialManagerError error);

 private:
  std::unique_ptr<blink::WebCredentialManagerClient::RequestCallbacks>
      callbacks_;

  DISALLOW_COPY_AND_ASSIGN(RequestCallbacksWrapper);
};

RequestCallbacksWrapper::RequestCallbacksWrapper(
    blink::WebCredentialManagerClient::RequestCallbacks* callbacks)
    : callbacks_(callbacks) {}

RequestCallbacksWrapper::~RequestCallbacksWrapper() {
  if (callbacks_)
    callbacks_->OnError(blink::kWebCredentialManagerUnknownError);
}

void RequestCallbacksWrapper::NotifySuccess(const CredentialInfo& info) {
  // Call onSuccess() and reset callbacks to avoid calling onError() in
  // destructor.
  if (callbacks_) {
    callbacks_->OnSuccess(CredentialInfoToWebCredential(info));
    callbacks_.reset();
  }
}

void RequestCallbacksWrapper::NotifyError(mojom::CredentialManagerError error) {
  if (callbacks_) {
    callbacks_->OnError(GetWebCredentialManagerErrorFromMojo(error));
    callbacks_.reset();
  }
}

void RespondToNotificationCallback(
    NotificationCallbacksWrapper* callbacks_wrapper) {
  callbacks_wrapper->NotifySuccess();
}

void RespondToRequestCallback(RequestCallbacksWrapper* callbacks_wrapper,
                              mojom::CredentialManagerError error,
                              const base::Optional<CredentialInfo>& info) {
  if (error == mojom::CredentialManagerError::SUCCESS) {
    DCHECK(info);
    callbacks_wrapper->NotifySuccess(*info);
  } else {
    DCHECK(!info);
    callbacks_wrapper->NotifyError(error);
  }
}

}  // namespace

CredentialManagerClient::CredentialManagerClient(
    content::RenderView* render_view)
    : content::RenderViewObserver(render_view) {
  render_view->GetWebView()->SetCredentialManagerClient(this);
}

CredentialManagerClient::~CredentialManagerClient() {}

// -----------------------------------------------------------------------------
// Access mojo CredentialManagerService.

void CredentialManagerClient::DispatchStore(
    const blink::WebCredential& credential,
    blink::WebCredentialManagerClient::NotificationCallbacks* callbacks) {
  DCHECK(callbacks);
  ConnectToMojoCMIfNeeded();

  CredentialInfo info;
  WebCredentialToCredentialInfo(credential, &info);
  mojo_cm_service_->Store(
      info,
      base::Bind(&RespondToNotificationCallback,
                 base::Owned(new NotificationCallbacksWrapper(callbacks))));
}

void CredentialManagerClient::DispatchPreventSilentAccess(
    blink::WebCredentialManagerClient::NotificationCallbacks* callbacks) {
  DCHECK(callbacks);
  ConnectToMojoCMIfNeeded();

  mojo_cm_service_->PreventSilentAccess(
      base::Bind(&RespondToNotificationCallback,
                 base::Owned(new NotificationCallbacksWrapper(callbacks))));
}

void CredentialManagerClient::DispatchGet(
    blink::WebCredentialMediationRequirement mediation,
    bool include_passwords,
    const blink::WebVector<blink::WebURL>& federations,
    RequestCallbacks* callbacks) {
  DCHECK(callbacks);
  ConnectToMojoCMIfNeeded();

  std::vector<GURL> federation_vector;
  for (size_t i = 0; i < std::min(federations.size(), kMaxFederations); ++i)
    federation_vector.push_back(federations[i]);

  mojo_cm_service_->Get(
      GetCredentialMediationRequirementFromBlink(mediation), include_passwords,
      federation_vector,
      base::Bind(&RespondToRequestCallback,
                 base::Owned(new RequestCallbacksWrapper(callbacks))));
}

void CredentialManagerClient::ConnectToMojoCMIfNeeded() {
  if (mojo_cm_service_)
    return;

  content::RenderFrame* main_frame = render_view()->GetMainRenderFrame();
  main_frame->GetRemoteInterfaces()->GetInterface(&mojo_cm_service_);
}

void CredentialManagerClient::OnDestruct() {
  delete this;
}

}  // namespace password_manager
