// Copyright 2019 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 "chrome/browser/download/deferred_client_wrapper.h"

#include <vector>

#include "base/bind.h"
#include "build/build_config.h"
#include "chrome/browser/android/startup_bridge.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/transition_manager/full_browser_transition_manager.h"
#include "components/download/public/background_service/clients.h"
#include "components/download/public/background_service/download_metadata.h"
#include "components/keyed_service/core/simple_factory_key.h"

namespace download {

DeferredClientWrapper::DeferredClientWrapper(ClientFactory client_factory,
                                             SimpleFactoryKey* key)
    : client_factory_(std::move(client_factory)), key_(key) {
#if defined(OS_ANDROID)
  full_browser_requested_ = false;
#endif

  FullBrowserTransitionManager::Get()->RegisterCallbackOnProfileCreation(
      key_, base::BindOnce(&DeferredClientWrapper::InflateClient,
                           weak_ptr_factory_.GetWeakPtr()));
#if !defined(OS_ANDROID)
  // On non-android platforms we can only be running in full browser mode. In
  // full browser mode, FullBrowserTransitionManager synchronously calls the
  // callback when it is registered.
  DCHECK(wrapped_client_);
#endif
}

DeferredClientWrapper::~DeferredClientWrapper() = default;

void DeferredClientWrapper::OnServiceInitialized(
    bool state_lost,
    const std::vector<DownloadMetaData>& downloads) {
  base::OnceClosure callback =
      base::BindOnce(&DeferredClientWrapper::ForwardOnServiceInitialized,
                     weak_ptr_factory_.GetWeakPtr(), state_lost, downloads);
  deferred_closures_.push_back(std::move(callback));

  bool force_inflate = downloads.size() > 0 || state_lost;
  RunDeferredClosures(force_inflate);
}

void DeferredClientWrapper::OnServiceUnavailable() {
  base::OnceClosure callback =
      base::BindOnce(&DeferredClientWrapper::ForwardOnServiceUnavailable,
                     weak_ptr_factory_.GetWeakPtr());
  deferred_closures_.push_back(std::move(callback));
  RunDeferredClosures(false /*force_inflate*/);
}

void DeferredClientWrapper::OnDownloadStarted(
    const std::string& guid,
    const std::vector<GURL>& url_chain,
    const scoped_refptr<const net::HttpResponseHeaders>& headers) {
  base::OnceClosure callback =
      base::BindOnce(&DeferredClientWrapper::ForwardOnDownloadStarted,
                     weak_ptr_factory_.GetWeakPtr(), guid, url_chain, headers);
  deferred_closures_.push_back(std::move(callback));
  RunDeferredClosures(true /*force_inflate*/);
}

void DeferredClientWrapper::OnDownloadUpdated(const std::string& guid,
                                              uint64_t bytes_uploaded,
                                              uint64_t bytes_downloaded) {
  base::OnceClosure callback = base::BindOnce(
      &DeferredClientWrapper::ForwardOnDownloadUpdated,
      weak_ptr_factory_.GetWeakPtr(), guid, bytes_uploaded, bytes_downloaded);
  deferred_closures_.push_back(std::move(callback));
  RunDeferredClosures(true /*force_inflate*/);
}

void DeferredClientWrapper::OnDownloadFailed(
    const std::string& guid,
    const download::CompletionInfo& info,
    FailureReason reason) {
  base::OnceClosure callback =
      base::BindOnce(&DeferredClientWrapper::ForwardOnDownloadFailed,
                     weak_ptr_factory_.GetWeakPtr(), guid, info, reason);
  deferred_closures_.push_back(std::move(callback));
  RunDeferredClosures(true /*force_inflate*/);
}

void DeferredClientWrapper::OnDownloadSucceeded(
    const std::string& guid,
    const CompletionInfo& completion_info) {
  base::OnceClosure callback =
      base::BindOnce(&DeferredClientWrapper::ForwardOnDownloadSucceeded,
                     weak_ptr_factory_.GetWeakPtr(), guid, completion_info);
  deferred_closures_.push_back(std::move(callback));
  RunDeferredClosures(true /*force_inflate*/);
}

bool DeferredClientWrapper::CanServiceRemoveDownloadedFile(
    const std::string& guid,
    bool force_delete) {
  base::OnceClosure callback = base::BindOnce(
      &DeferredClientWrapper::ForwardCanServiceRemoveDownloadedFile,
      weak_ptr_factory_.GetWeakPtr(), guid, force_delete);
  deferred_closures_.push_back(std::move(callback));
  RunDeferredClosures(force_delete /*force_inflate*/);
  return false;
}

void DeferredClientWrapper::GetUploadData(
    const std::string& guid,
    GetUploadDataCallback upload_callback) {
  base::OnceClosure callback = base::BindOnce(
      &DeferredClientWrapper::ForwardGetUploadData,
      weak_ptr_factory_.GetWeakPtr(), guid, std::move(upload_callback));
  deferred_closures_.push_back(std::move(callback));
  RunDeferredClosures(true /*force_inflate*/);
}

void DeferredClientWrapper::ForwardOnServiceInitialized(
    bool state_lost,
    const std::vector<DownloadMetaData>& downloads) {
  wrapped_client_->OnServiceInitialized(state_lost, downloads);
}

void DeferredClientWrapper::ForwardOnServiceUnavailable() {
  wrapped_client_->OnServiceUnavailable();
}

void DeferredClientWrapper::ForwardOnDownloadStarted(
    const std::string& guid,
    const std::vector<GURL>& url_chain,
    const scoped_refptr<const net::HttpResponseHeaders>& headers) {
  wrapped_client_->OnDownloadStarted(guid, url_chain, headers);
}

void DeferredClientWrapper::ForwardOnDownloadUpdated(
    const std::string& guid,
    uint64_t bytes_uploaded,
    uint64_t bytes_downloaded) {
  wrapped_client_->OnDownloadUpdated(guid, bytes_uploaded, bytes_downloaded);
}

void DeferredClientWrapper::ForwardOnDownloadFailed(
    const std::string& guid,
    const download::CompletionInfo& info,
    FailureReason reason) {
  wrapped_client_->OnDownloadFailed(guid, info, reason);
}

void DeferredClientWrapper::ForwardOnDownloadSucceeded(
    const std::string& guid,
    const CompletionInfo& completion_info) {
  wrapped_client_->OnDownloadSucceeded(guid, completion_info);
}

void DeferredClientWrapper::ForwardCanServiceRemoveDownloadedFile(
    const std::string& guid,
    bool force_delete) {
  wrapped_client_->CanServiceRemoveDownloadedFile(guid, force_delete);
}

void DeferredClientWrapper::ForwardGetUploadData(
    const std::string& guid,
    GetUploadDataCallback callback) {
  wrapped_client_->GetUploadData(guid, std::move(callback));
}

void DeferredClientWrapper::RunDeferredClosures(bool force_inflate) {
  if (wrapped_client_) {
    DoRunDeferredClosures();
  } else if (force_inflate) {
#if defined(OS_ANDROID)
    // The constructor registers InflateClient as a callback with
    // FullBrowserTransitionManager on Profile creation. We just need to trigger
    // loading full browser. Once full browser is loaded and  profile is
    // created, FullBrowserTransitionManager will call InflateClient.
    LaunchFullBrowser();
#else
    // For platforms that do not implement reduced mode (i.e. non-android), the
    // wrapped client should have been inflated in the constructor.
    NOTREACHED();
#endif
  }
}

void DeferredClientWrapper::DoRunDeferredClosures() {
  DCHECK(wrapped_client_);
  auto deferred_closures = std::move(deferred_closures_);
  for (auto& closure : deferred_closures) {
    std::move(closure).Run();
  }
}

void DeferredClientWrapper::InflateClient(Profile* profile) {
  DCHECK(profile);
  DCHECK(client_factory_);
  wrapped_client_ = std::move(client_factory_).Run(profile);
  DoRunDeferredClosures();
}

#if defined(OS_ANDROID)
void DeferredClientWrapper::LaunchFullBrowser() {
  if (full_browser_requested_)
    return;
  full_browser_requested_ = true;
  android_startup::LoadFullBrowser();
}
#endif

}  // namespace download
