// 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/background_fetch/background_fetch_job_controller.h"
#include "content/browser/background_fetch/background_fetch_data_manager.h"
#include "content/browser/background_fetch/background_fetch_request_match_params.h"
#include "content/public/common/origin_util.h"
#include "services/network/public/cpp/cors/cors.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h"

#include <utility>

#include "content/public/browser/browser_thread.h"

namespace content {

namespace {

// Performs mixed content checks on the |request| for Background Fetch.
// Background Fetch depends on Service Workers, which are restricted for use
// on secure origins. We can therefore assume that the registration's origin
// is secure. This test ensures that the origin for the url of every
// request is also secure.
bool IsMixedContent(const BackgroundFetchRequestInfo& request) {
  // Empty request is valid, it shouldn't fail the mixed content check.
  if (request.fetch_request()->url.is_empty())
    return false;

  return !IsOriginSecure(request.fetch_request()->url);
}

// Whether the |request| needs CORS preflight.
// Requests that require CORS preflights are temporarily blocked, because the
// browser side of Background Fetch doesn't yet support performing CORS
// checks. TODO(crbug.com/711354): Remove this temporary block.
bool RequiresCorsPreflight(const BackgroundFetchRequestInfo& request,
                           const url::Origin& origin) {
  const blink::mojom::FetchAPIRequestPtr& fetch_request =
      request.fetch_request();

  // Same origin requests don't require a CORS preflight.
  // https://fetch.spec.whatwg.org/#main-fetch
  // TODO(crbug.com/711354): Make sure that cross-origin redirects are disabled.
  if (url::IsSameOriginWith(origin.GetURL(), fetch_request->url))
    return false;

  // Requests that are more involved than what is possible with HTML's form
  // element require a CORS-preflight request.
  // https://fetch.spec.whatwg.org/#main-fetch
  if (!fetch_request->method.empty() &&
      !network::cors::IsCorsSafelistedMethod(fetch_request->method)) {
    return true;
  }

  net::HttpRequestHeaders::HeaderVector headers;
  for (const auto& header : fetch_request->headers)
    headers.emplace_back(header.first, header.second);

  return !network::cors::CorsUnsafeRequestHeaderNames(headers).empty();
}

}  // namespace

using blink::mojom::BackgroundFetchError;
using blink::mojom::BackgroundFetchFailureReason;

BackgroundFetchJobController::BackgroundFetchJobController(
    BackgroundFetchDataManager* data_manager,
    BackgroundFetchDelegateProxy* delegate_proxy,
    const BackgroundFetchRegistrationId& registration_id,
    blink::mojom::BackgroundFetchOptionsPtr options,
    const SkBitmap& icon,
    uint64_t bytes_downloaded,
    ProgressCallback progress_callback,
    FinishedCallback finished_callback)
    : data_manager_(data_manager),
      delegate_proxy_(delegate_proxy),
      registration_id_(registration_id),
      options_(std::move(options)),
      icon_(icon),
      complete_requests_downloaded_bytes_cache_(bytes_downloaded),
      progress_callback_(std::move(progress_callback)),
      finished_callback_(std::move(finished_callback)),
      weak_ptr_factory_(this) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
}

void BackgroundFetchJobController::InitializeRequestStatus(
    int completed_downloads,
    int total_downloads,
    std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
        active_fetch_requests,
    bool start_paused) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  // Don't allow double initialization.
  DCHECK_GT(total_downloads, 0);
  DCHECK_EQ(total_downloads_, 0);

  completed_downloads_ = completed_downloads;
  total_downloads_ = total_downloads;

  std::vector<std::string> active_guids;
  active_guids.reserve(active_fetch_requests.size());
  for (const auto& request_info : active_fetch_requests)
    active_guids.push_back(request_info->download_guid());

  auto fetch_description = std::make_unique<BackgroundFetchDescription>(
      registration_id().unique_id(), options_->title,
      registration_id().origin(), icon_, completed_downloads, total_downloads,
      complete_requests_downloaded_bytes_cache_, options_->download_total,
      std::move(active_guids), start_paused);

  delegate_proxy_->CreateDownloadJob(GetWeakPtr(), std::move(fetch_description),
                                     std::move(active_fetch_requests));
}

BackgroundFetchJobController::~BackgroundFetchJobController() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
}

bool BackgroundFetchJobController::HasMoreRequests() {
  return completed_downloads_ < total_downloads_;
}

void BackgroundFetchJobController::StartRequest(
    scoped_refptr<BackgroundFetchRequestInfo> request,
    RequestFinishedCallback request_finished_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  DCHECK_LT(completed_downloads_, total_downloads_);
  DCHECK(request_finished_callback);
  DCHECK(request);

  active_request_downloaded_bytes_ = 0;
  active_request_finished_callback_ = std::move(request_finished_callback);

  if (IsMixedContent(*request.get()) ||
      RequiresCorsPreflight(*request.get(), registration_id_.origin())) {
    request->SetEmptyResultWithFailureReason(
        BackgroundFetchResult::FailureReason::FETCH_ERROR);

    ++completed_downloads_;
    std::move(active_request_finished_callback_).Run(request);
    return;
  }

  delegate_proxy_->StartRequest(registration_id().unique_id(),
                                registration_id().origin(), request);
}

void BackgroundFetchJobController::DidStartRequest(
    const scoped_refptr<BackgroundFetchRequestInfo>& request) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  // TODO(crbug.com/884672): Either add CORS check here or remove this function
  // and do the CORS check in BackgroundFetchDelegateImpl (since
  // download::Client::OnDownloadStarted returns a value that can abort the
  // download).
}

void BackgroundFetchJobController::DidUpdateRequest(
    const scoped_refptr<BackgroundFetchRequestInfo>& request,
    uint64_t bytes_downloaded) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  if (active_request_downloaded_bytes_ == bytes_downloaded)
    return;

  active_request_downloaded_bytes_ = bytes_downloaded;

  auto registration = NewRegistration();
  registration->downloaded += GetInProgressDownloadedBytes();
  progress_callback_.Run(*registration);
}

void BackgroundFetchJobController::DidCompleteRequest(
    const scoped_refptr<BackgroundFetchRequestInfo>& request) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  // It's possible for the DidCompleteRequest() callback to have been in-flight
  // while this Job Controller was being aborted, in which case the
  // |active_request_finished_callback_| will have been reset.
  if (!active_request_finished_callback_)
    return;

  active_request_downloaded_bytes_ = 0;

  complete_requests_downloaded_bytes_cache_ += request->GetFileSize();
  ++completed_downloads_;

  std::move(active_request_finished_callback_).Run(request);
}

blink::mojom::BackgroundFetchRegistrationPtr
BackgroundFetchJobController::NewRegistration() const {
  return blink::mojom::BackgroundFetchRegistration::New(
      registration_id().developer_id(), registration_id().unique_id(),
      0 /* upload_total */, 0 /* uploaded */, options_->download_total,
      complete_requests_downloaded_bytes_cache_,
      blink::mojom::BackgroundFetchResult::UNSET, failure_reason_);
}

uint64_t BackgroundFetchJobController::GetInProgressDownloadedBytes() {
  return active_request_downloaded_bytes_;
}

void BackgroundFetchJobController::AbortFromDelegate(
    BackgroundFetchFailureReason failure_reason) {
  failure_reason_ = failure_reason;

  // Stop propagating any in-flight events to the scheduler.
  active_request_finished_callback_.Reset();

  Finish(failure_reason_, base::DoNothing());
}

void BackgroundFetchJobController::Abort(
    BackgroundFetchFailureReason failure_reason,
    ErrorCallback callback) {
  failure_reason_ = failure_reason;

  // Stop propagating any in-flight events to the scheduler.
  active_request_finished_callback_.Reset();

  // Cancel any in-flight downloads and UI through the BGFetchDelegate.
  delegate_proxy_->Abort(registration_id().unique_id());

  Finish(failure_reason_, std::move(callback));
}

void BackgroundFetchJobController::Finish(
    BackgroundFetchFailureReason reason_to_abort,
    ErrorCallback callback) {
  DCHECK(reason_to_abort != BackgroundFetchFailureReason::NONE ||
         !HasMoreRequests());

  // Race conditions make it possible for a controller to finish twice. This
  // should be removed when the scheduler starts owning the controllers.
  if (!finished_callback_) {
    std::move(callback).Run(BackgroundFetchError::INVALID_ID);
    return;
  }

  std::move(finished_callback_)
      .Run(registration_id_, reason_to_abort, std::move(callback));
}

void BackgroundFetchJobController::DidPopNextRequest(
    BackgroundFetchError error,
    scoped_refptr<BackgroundFetchRequestInfo> request_info) {
  if (error != BackgroundFetchError::NONE) {
    Abort(BackgroundFetchFailureReason::SERVICE_WORKER_UNAVAILABLE,
          base::DoNothing());
    return;
  }

  StartRequest(
      std::move(request_info),
      base::BindOnce(&BackgroundFetchJobController::MarkRequestAsComplete,
                     GetWeakPtr()));
}

void BackgroundFetchJobController::MarkRequestAsComplete(
    scoped_refptr<BackgroundFetchRequestInfo> request_info) {
  data_manager_->MarkRequestAsComplete(
      registration_id(), std::move(request_info),
      base::BindOnce(&BackgroundFetchJobController::DidMarkRequestAsComplete,
                     GetWeakPtr()));
}

void BackgroundFetchJobController::DidMarkRequestAsComplete(
    BackgroundFetchError error) {
  switch (error) {
    case BackgroundFetchError::NONE:
      break;
    case BackgroundFetchError::STORAGE_ERROR:
      Abort(BackgroundFetchFailureReason::SERVICE_WORKER_UNAVAILABLE,
            base::DoNothing());
      return;
    case BackgroundFetchError::QUOTA_EXCEEDED:
      Abort(BackgroundFetchFailureReason::QUOTA_EXCEEDED, base::DoNothing());
      return;
    default:
      NOTREACHED();
  }

  if (HasMoreRequests()) {
    data_manager_->PopNextRequest(
        registration_id(),
        base::BindOnce(&BackgroundFetchJobController::DidPopNextRequest,
                       GetWeakPtr()));
    return;
  }
  Finish(BackgroundFetchFailureReason::NONE, base::DoNothing());
}

void BackgroundFetchJobController::GetUploadData(
    blink::mojom::FetchAPIRequestPtr request,
    BackgroundFetchDelegate::GetUploadDataCallback callback) {
  data_manager_->MatchRequests(
      registration_id(),
      std::make_unique<BackgroundFetchRequestMatchParams>(
          std::move(request), /* match_params= */ nullptr,
          /* match_all= */ false),
      base::BindOnce(&BackgroundFetchJobController::DidGetUploadData,
                     GetWeakPtr(), std::move(callback)));
}

void BackgroundFetchJobController::DidGetUploadData(
    BackgroundFetchDelegate::GetUploadDataCallback callback,
    BackgroundFetchError error,
    std::vector<blink::mojom::BackgroundFetchSettledFetchPtr> fetches) {
  if (error != BackgroundFetchError::NONE) {
    Abort(BackgroundFetchFailureReason::SERVICE_WORKER_UNAVAILABLE,
          base::DoNothing());
    std::move(callback).Run(/* request_body= */ nullptr);
    return;
  }

  DCHECK_EQ(fetches.size(), 1u);
  DCHECK(fetches[0]->request->blob);

  network::mojom::DataPipeGetterPtr data_pipe_getter_ptr;
  blink::mojom::BlobPtr blob_ptr(std::move(fetches[0]->request->blob->blob));
  blob_ptr->AsDataPipeGetter(MakeRequest(&data_pipe_getter_ptr));

  auto request_body = base::MakeRefCounted<network::ResourceRequestBody>();
  request_body->AppendDataPipe(std::move(data_pipe_getter_ptr));
  std::move(callback).Run(std::move(request_body));
}

}  // namespace content
