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

#include "content/browser/payments/respond_with_callback.h"

#include "content/browser/payments/payment_app_provider_impl.h"
#include "content/browser/payments/payment_event_dispatcher.h"

namespace content {

namespace {

using payments::mojom::CanMakePaymentEventResponseType;
using payments::mojom::CanMakePaymentResponsePtr;
using payments::mojom::PaymentEventResponseType;
using payments::mojom::PaymentHandlerResponseCallback;
using payments::mojom::PaymentHandlerResponsePtr;

}  // namespace

mojo::PendingRemote<PaymentHandlerResponseCallback>
RespondWithCallback::BindNewPipeAndPassRemote() {
  return receiver_.BindNewPipeAndPassRemote();
}

RespondWithCallback::RespondWithCallback(
    ServiceWorkerMetrics::EventType event_type,
    scoped_refptr<ServiceWorkerVersion> service_worker_version,
    base::WeakPtr<PaymentEventDispatcher> event_dispatcher)
    : service_worker_version_(service_worker_version),
      event_dispatcher_(event_dispatcher) {
  request_id_ = service_worker_version->StartRequest(
      event_type, base::BindOnce(&RespondWithCallback::OnServiceWorkerError,
                                 weak_ptr_factory_.GetWeakPtr()));
}

RespondWithCallback::~RespondWithCallback() = default;

void RespondWithCallback::FinishServiceWorkerRequest() {
  service_worker_version_->FinishRequest(request_id_, /*was_handled=*/false);
}

void RespondWithCallback::MaybeRecordTimeoutMetric(
    blink::ServiceWorkerStatusCode status) {
  if (status == blink::ServiceWorkerStatusCode::kErrorTimeout) {
    UMA_HISTOGRAM_BOOLEAN("PaymentRequest.ServiceWorkerStatusCodeTimeout",
                          true);
  }
}

void RespondWithCallback::ClearRespondWithCallbackAndCloseWindow() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!event_dispatcher_)
    return;

  if (base::WeakPtr<PaymentAppProviderImpl> provider =
          event_dispatcher_->payment_app_provider())
    provider->CloseOpenedWindow();

  event_dispatcher_->ResetRespondWithCallback();
}

CanMakePaymentRespondWithCallback::CanMakePaymentRespondWithCallback(
    scoped_refptr<ServiceWorkerVersion> service_worker_version,
    base::WeakPtr<PaymentEventDispatcher> event_dispatcher,
    PaymentAppProvider::CanMakePaymentCallback callback)
    : RespondWithCallback(ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT,
                          service_worker_version,
                          event_dispatcher),
      callback_(std::move(callback)) {}

CanMakePaymentRespondWithCallback::~CanMakePaymentRespondWithCallback() =
    default;

void CanMakePaymentRespondWithCallback::OnResponseForCanMakePayment(
    CanMakePaymentResponsePtr response) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  FinishServiceWorkerRequest();
  std::move(callback_).Run(std::move(response));
  delete this;
}

void CanMakePaymentRespondWithCallback::OnServiceWorkerError(
    blink::ServiceWorkerStatusCode service_worker_status) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
  MaybeRecordTimeoutMetric(service_worker_status);

  CanMakePaymentEventResponseType response_type =
      CanMakePaymentEventResponseType::BROWSER_ERROR;
  if (service_worker_status ==
      blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected) {
    response_type = CanMakePaymentEventResponseType::REJECT;
  } else if (service_worker_status ==
             blink::ServiceWorkerStatusCode::kErrorTimeout) {
    response_type = CanMakePaymentEventResponseType::TIMEOUT;
  }

  std::move(callback_).Run(
      content::PaymentAppProviderUtil::CreateBlankCanMakePaymentResponse(
          response_type));
  delete this;
}

InvokeRespondWithCallback::InvokeRespondWithCallback(
    scoped_refptr<ServiceWorkerVersion> service_worker_version,
    base::WeakPtr<PaymentEventDispatcher> event_dispatcher,
    PaymentAppProvider::InvokePaymentAppCallback callback)
    : RespondWithCallback(ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
                          service_worker_version,
                          event_dispatcher),
      callback_(std::move(callback)) {}

void InvokeRespondWithCallback::AbortPaymentSinceOpennedWindowClosing(
    PaymentEventResponseType reason) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  FinishServiceWorkerRequest();
  RespondToPaymentRequestWithErrorAndDeleteSelf(reason);
}

InvokeRespondWithCallback::~InvokeRespondWithCallback() = default;

void InvokeRespondWithCallback::OnResponseForPaymentRequest(
    PaymentHandlerResponsePtr response) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  FinishServiceWorkerRequest();
  std::move(callback_).Run(std::move(response));
  ClearRespondWithCallbackAndCloseWindow();
}

void InvokeRespondWithCallback::OnServiceWorkerError(
    blink::ServiceWorkerStatusCode service_worker_status) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
  MaybeRecordTimeoutMetric(service_worker_status);

  PaymentEventResponseType response_type =
      PaymentEventResponseType::PAYMENT_EVENT_BROWSER_ERROR;
  if (service_worker_status ==
      blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected) {
    response_type = PaymentEventResponseType::PAYMENT_EVENT_REJECT;
  } else if (service_worker_status ==
             blink::ServiceWorkerStatusCode::kErrorTimeout) {
    response_type = PaymentEventResponseType::PAYMENT_EVENT_TIMEOUT;
  }

  RespondToPaymentRequestWithErrorAndDeleteSelf(response_type);
}

void InvokeRespondWithCallback::RespondToPaymentRequestWithErrorAndDeleteSelf(
    PaymentEventResponseType response_type) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  std::move(callback_).Run(
      content::PaymentAppProviderUtil::CreateBlankPaymentHandlerResponse(
          response_type));
  ClearRespondWithCallbackAndCloseWindow();
}

AbortRespondWithCallback::AbortRespondWithCallback(
    scoped_refptr<ServiceWorkerVersion> service_worker_version,
    base::WeakPtr<PaymentEventDispatcher> event_dispatcher,
    PaymentAppProvider::AbortCallback callback)
    : RespondWithCallback(ServiceWorkerMetrics::EventType::ABORT_PAYMENT,
                          service_worker_version,
                          event_dispatcher),
      callback_(std::move(callback)) {}

AbortRespondWithCallback::~AbortRespondWithCallback() = default;

// PaymentHandlerResponseCallback implementation.
void AbortRespondWithCallback::OnResponseForAbortPayment(bool payment_aborted) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  FinishServiceWorkerRequest();
  std::move(callback_).Run(payment_aborted);

  if (payment_aborted)
    ClearRespondWithCallbackAndCloseWindow();

  delete this;
}

void AbortRespondWithCallback::OnServiceWorkerError(
    blink::ServiceWorkerStatusCode service_worker_status) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK_NE(service_worker_status, blink::ServiceWorkerStatusCode::kOk);
  MaybeRecordTimeoutMetric(service_worker_status);
  std::move(callback_).Run(/*payment_aborted=*/false);
  // Do not call ClearRespondWithCallbackAndCloseWindow() here, because payment
  // has not been aborted. The service worker either rejected, timed out, or
  // threw a JavaScript exception in the "abortpayment" event, but that does
  // not affect the ongoing "paymentrequest" event.
  delete this;
}

}  // namespace content
