// Copyright 2018 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 "services/network/http_cache_data_remover.h"

#include <set>
#include <string>

#include "base/bind.h"
#include "base/location.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "url/gurl.h"

namespace network {

namespace {

bool DoesUrlMatchFilter(mojom::ClearDataFilter_Type filter_type,
                        const std::set<url::Origin>& origins,
                        const std::set<std::string>& domains,
                        const GURL& url) {
  std::string url_registerable_domain =
      net::registry_controlled_domains::GetDomainAndRegistry(
          url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
  bool found_domain = (domains.find(url_registerable_domain != ""
                                        ? url_registerable_domain
                                        : url.host()) != domains.end());

  bool found_origin = (origins.find(url::Origin::Create(url)) != origins.end());

  return ((found_domain || found_origin) ==
          (filter_type == mojom::ClearDataFilter_Type::DELETE_MATCHES));
}

}  // namespace

HttpCacheDataRemover::HttpCacheDataRemover(
    mojom::ClearDataFilterPtr url_filter,
    base::Time delete_begin,
    base::Time delete_end,
    HttpCacheDataRemoverCallback done_callback)
    : delete_begin_(delete_begin),
      delete_end_(delete_end),
      done_callback_(std::move(done_callback)),
      backend_(nullptr),
      weak_factory_(this) {
  DCHECK(!done_callback_.is_null());

  if (!url_filter)
    return;

  // Use the filter to create the |url_matcher_| callback.
  std::set<std::string> domains;
  domains.insert(url_filter->domains.begin(), url_filter->domains.end());

  std::set<url::Origin> origins;
  origins.insert(url_filter->origins.begin(), url_filter->origins.end());

  url_matcher_ = base::BindRepeating(&DoesUrlMatchFilter, url_filter->type,
                                     origins, domains);
}

HttpCacheDataRemover::~HttpCacheDataRemover() = default;

// static.
std::unique_ptr<HttpCacheDataRemover> HttpCacheDataRemover::CreateAndStart(
    net::URLRequestContext* url_request_context,
    mojom::ClearDataFilterPtr url_filter,
    base::Time delete_begin,
    base::Time delete_end,
    HttpCacheDataRemoverCallback done_callback) {
  DCHECK(done_callback);
  std::unique_ptr<HttpCacheDataRemover> remover(
      new HttpCacheDataRemover(std::move(url_filter), delete_begin, delete_end,
                               std::move(done_callback)));

  net::HttpCache* http_cache =
      url_request_context->http_transaction_factory()->GetCache();
  if (!http_cache) {
    // Some contexts might not have a cache, in which case we are done.
    // Notify by posting a task to avoid reentrency.
    base::SequencedTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&HttpCacheDataRemover::ClearHttpCacheDone,
                       remover->weak_factory_.GetWeakPtr(), net::OK));
    return remover;
  }

  // Clear QUIC server information from memory and the disk cache.
  // TODO(crbug.com/817849): add a browser test to validate the QUIC information
  // is cleared.
  http_cache->GetSession()
      ->quic_stream_factory()
      ->ClearCachedStatesInCryptoConfig(remover->url_matcher_);

  net::CompletionOnceCallback callback =
      base::BindOnce(&HttpCacheDataRemover::CacheRetrieved,
                     remover->weak_factory_.GetWeakPtr());
  int rv = http_cache->GetBackend(&remover->backend_, std::move(callback));
  if (rv != net::ERR_IO_PENDING) {
    remover->CacheRetrieved(rv);
  }
  return remover;
}

void HttpCacheDataRemover::CacheRetrieved(int rv) {
  DCHECK(done_callback_);

  // |backend_| can be null if it cannot be initialized.
  if (rv != net::OK || !backend_) {
    backend_ = nullptr;
    base::SequencedTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&HttpCacheDataRemover::ClearHttpCacheDone,
                                  weak_factory_.GetWeakPtr(), rv));
    return;
  }

  if (!url_matcher_.is_null()) {
    deletion_helper_ = ConditionalCacheDeletionHelper::CreateAndStart(
        backend_, url_matcher_, delete_begin_, delete_end_,
        base::BindOnce(&HttpCacheDataRemover::ClearHttpCacheDone,
                       weak_factory_.GetWeakPtr(), net::OK));
    return;
  }

  if (delete_begin_.is_null() && delete_end_.is_max()) {
    rv = backend_->DoomAllEntries(base::Bind(
        &HttpCacheDataRemover::ClearHttpCacheDone, weak_factory_.GetWeakPtr()));
  } else {
    rv = backend_->DoomEntriesBetween(
        delete_begin_, delete_end_,
        base::Bind(&HttpCacheDataRemover::ClearHttpCacheDone,
                   weak_factory_.GetWeakPtr()));
  }
  if (rv != net::ERR_IO_PENDING) {
    // Notify by posting a task to avoid reentrency.
    base::SequencedTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&HttpCacheDataRemover::ClearHttpCacheDone,
                                  weak_factory_.GetWeakPtr(), rv));
  }
}

void HttpCacheDataRemover::ClearHttpCacheDone(int rv) {
  std::move(done_callback_).Run(this);
}

}  // namespace network
