// 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 "content/browser/payments/payment_app_provider_impl.h"

#include "content/browser/payments/payment_app_context_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"

namespace content {
namespace {

void DidGetAllManifestsOnIO(
    const PaymentAppProvider::GetAllManifestsCallback& callback,
    PaymentAppProvider::Manifests manifests) {
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(callback, base::Passed(std::move(manifests))));
}

void GetAllManifestsOnIO(
    scoped_refptr<PaymentAppContextImpl> payment_app_context,
    const PaymentAppProvider::GetAllManifestsCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  payment_app_context->payment_app_database()->ReadAllManifests(
      base::Bind(&DidGetAllManifestsOnIO, callback));
}

void DidDispatchPaymentRequestEvent(
    scoped_refptr<ServiceWorkerVersion> active_version,
    int request_id,
    ServiceWorkerStatusCode service_worker_status,
    base::Time dispatch_event_time) {
  active_version->FinishRequest(request_id,
                                service_worker_status == SERVICE_WORKER_OK,
                                dispatch_event_time);
}

void DispatchPaymentRequestEventError(
    ServiceWorkerStatusCode service_worker_status) {
  NOTIMPLEMENTED();
}

void DispatchPaymentRequestEvent(
    payments::mojom::PaymentAppRequestDataPtr data,
    scoped_refptr<ServiceWorkerVersion> active_version) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  DCHECK(active_version);

  int request_id = active_version->StartRequest(
      ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
      base::Bind(&DispatchPaymentRequestEventError));

  active_version->event_dispatcher()->DispatchPaymentRequestEvent(
      std::move(data),
      base::Bind(&DidDispatchPaymentRequestEvent, active_version, request_id));
}

void DidFindRegistrationOnIO(
    payments::mojom::PaymentAppRequestDataPtr data,
    ServiceWorkerStatusCode service_worker_status,
    scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  if (service_worker_status != SERVICE_WORKER_OK)
    return;

  ServiceWorkerVersion* active_version =
      service_worker_registration->active_version();
  DCHECK(active_version);
  active_version->RunAfterStartWorker(
      ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
      base::Bind(&DispatchPaymentRequestEvent, base::Passed(std::move(data)),
                 make_scoped_refptr(active_version)),
      base::Bind(&DispatchPaymentRequestEventError));
}

void FindRegistrationOnIO(
    scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
    int64_t registration_id,
    payments::mojom::PaymentAppRequestDataPtr data) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  service_worker_context->FindReadyRegistrationForIdOnly(
      registration_id,
      base::Bind(&DidFindRegistrationOnIO, base::Passed(std::move(data))));
}

}  // namespace

// static
PaymentAppProvider* PaymentAppProvider::GetInstance() {
  return PaymentAppProviderImpl::GetInstance();
}

// static
PaymentAppProviderImpl* PaymentAppProviderImpl::GetInstance() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  return base::Singleton<PaymentAppProviderImpl>::get();
}

void PaymentAppProviderImpl::GetAllManifests(
    BrowserContext* browser_context,
    const GetAllManifestsCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
      BrowserContext::GetDefaultStoragePartition(browser_context));
  scoped_refptr<PaymentAppContextImpl> payment_app_context =
      partition->GetPaymentAppContext();

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&GetAllManifestsOnIO, payment_app_context, callback));
}

void PaymentAppProviderImpl::InvokePaymentApp(
    BrowserContext* browser_context,
    int64_t registration_id,
    payments::mojom::PaymentAppRequestDataPtr data) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
      BrowserContext::GetDefaultStoragePartition(browser_context));
  scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
      partition->GetServiceWorkerContext();

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&FindRegistrationOnIO, std::move(service_worker_context),
                 registration_id, base::Passed(std::move(data))));
}

PaymentAppProviderImpl::PaymentAppProviderImpl() {}

PaymentAppProviderImpl::~PaymentAppProviderImpl() {}

}  // namespace content
