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

#include "net/disk_cache/disk_cache.h"

#include <utility>

#include "base/barrier_closure.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/field_trial.h"
#include "base/task/bind_post_task.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "build/build_config.h"
#include "build/buildflag.h"
#include "net/base/cache_type.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/backend_cleanup_tracker.h"
#include "net/disk_cache/basic_cache_file.h"
#include "net/disk_cache/blockfile/backend_impl.h"
#include "net/disk_cache/buildflags.h"
#include "net/disk_cache/cache_encryption_delegate.h"
#include "net/disk_cache/cache_util.h"
#include "net/disk_cache/disk_cache.h"
#include "net/disk_cache/memory/mem_backend_impl.h"
#include "net/disk_cache/simple/simple_backend_impl.h"
#include "net/disk_cache/simple/simple_file_enumerator.h"
#include "net/disk_cache/simple/simple_util.h"

#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
#include "net/disk_cache/sql/sql_backend_impl.h"
#endif  // ENABLE_DISK_CACHE_SQL_BACKEND

namespace {

using FileEnumerator = disk_cache::BackendFileOperations::FileEnumerator;
using ApplicationStatusListenerGetter =
    disk_cache::ApplicationStatusListenerGetter;

// Builds an instance of the backend depending on platform, type, experiments
// etc. Takes care of the retry state. This object will self-destroy when
// finished.
class CacheCreator {
 public:
  CacheCreator(const base::FilePath& path,
               disk_cache::ResetHandling reset_handling,
               int64_t max_bytes,
               net::CacheType type,
               net::BackendType backend_type,
               scoped_refptr<disk_cache::BackendFileOperationsFactory>
                   file_operations_factory,
#if BUILDFLAG(IS_ANDROID)
               ApplicationStatusListenerGetter app_status_listener_getter,
#endif
               net::NetLog* net_log,
               net::CacheEncryptionDelegate* cache_encryption_delegate,
               base::OnceClosure post_cleanup_callback,
               disk_cache::BackendResultCallback callback);

  CacheCreator(const CacheCreator&) = delete;
  CacheCreator& operator=(const CacheCreator&) = delete;

  // Wait for any previous backends for given path to finish clean up and then
  // attempt to create a new one. This is always asynchronous.
  void TryCreateCleanupTrackerAndRun();

  // Queues an asynchronous failure.
  void FailAttempt();

  // Special entry point for DISK_CACHE that initializes encryption
  // but skips the cleanup tracker.
  void InitEncryptionAndRun();

 private:
  ~CacheCreator();

  // Creates the backend, the cleanup context for it having been already
  // established... or purposefully left as null. This is always asynchronous.
  void Run();

  void DoCallback(int result);

  void OnEncryptionInitComplete(net::Error result);
  void OnIOComplete(int result);
  void OnCacheCleanupComplete(int original_error, bool cleanup_result);

  const base::FilePath path_;
  disk_cache::ResetHandling reset_handling_;
  bool retry_ = false;
  int64_t max_bytes_;
  net::CacheType type_;
  net::BackendType backend_type_;
  scoped_refptr<disk_cache::BackendFileOperationsFactory>
      file_operations_factory_;
  std::unique_ptr<disk_cache::BackendFileOperations> file_operations_;
#if BUILDFLAG(IS_ANDROID)
  ApplicationStatusListenerGetter app_status_listener_getter_;
#endif
  base::OnceClosure post_cleanup_callback_;
  disk_cache::BackendResultCallback callback_;
  std::unique_ptr<disk_cache::Backend> created_cache_;
  raw_ptr<net::NetLog> net_log_;
  scoped_refptr<disk_cache::BackendCleanupTracker> cleanup_tracker_;
  raw_ptr<net::CacheEncryptionDelegate> cache_encryption_delegate_;
};

CacheCreator::CacheCreator(
    const base::FilePath& path,
    disk_cache::ResetHandling reset_handling,
    int64_t max_bytes,
    net::CacheType type,
    net::BackendType backend_type,
    scoped_refptr<disk_cache::BackendFileOperationsFactory> file_operations,
#if BUILDFLAG(IS_ANDROID)
    ApplicationStatusListenerGetter app_status_listener_getter,
#endif
    net::NetLog* net_log,
    net::CacheEncryptionDelegate* cache_encryption_delegate,
    base::OnceClosure post_cleanup_callback,
    disk_cache::BackendResultCallback callback)
    : path_(path),
      reset_handling_(reset_handling),
      max_bytes_(max_bytes),
      type_(type),
      backend_type_(backend_type),
      file_operations_factory_(std::move(file_operations)),
#if BUILDFLAG(IS_ANDROID)
      app_status_listener_getter_(std::move(app_status_listener_getter)),
#endif
      post_cleanup_callback_(std::move(post_cleanup_callback)),
      callback_(std::move(callback)),
      net_log_(net_log),
      cache_encryption_delegate_(cache_encryption_delegate) {
}

CacheCreator::~CacheCreator() = default;

void CacheCreator::Run() {
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
  static const bool kSimpleBackendIsDefault = true;
#else
  static const bool kSimpleBackendIsDefault = false;
#endif
  if (!retry_ && reset_handling_ == disk_cache::ResetHandling::kReset) {
    // Pretend that we failed to create a cache, so that we can handle `kReset`
    // and `kResetOnError` in a unified way, in CacheCreator::OnIOComplete.
    FailAttempt();
    return;
  }
  if (backend_type_ == net::CACHE_BACKEND_SIMPLE ||
      (backend_type_ == net::CACHE_BACKEND_DEFAULT &&
       kSimpleBackendIsDefault)) {
    auto cache = std::make_unique<disk_cache::SimpleBackendImpl>(
        file_operations_factory_, path_, cleanup_tracker_.get(),
        /* file_tracker = */ nullptr, max_bytes_, type_, net_log_,
        cache_encryption_delegate_);
    disk_cache::SimpleBackendImpl* simple_cache = cache.get();
    created_cache_ = std::move(cache);
#if BUILDFLAG(IS_ANDROID)
    if (app_status_listener_getter_) {
      simple_cache->set_app_status_listener_getter(app_status_listener_getter_);
    }
#endif
    simple_cache->Init(
        base::BindOnce(&CacheCreator::OnIOComplete, base::Unretained(this)));
    return;
  }

#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
  if (backend_type_ == net::CACHE_BACKEND_EXPERIMENTAL_SQL) {
    auto sql_cache =
        std::make_unique<disk_cache::SqlBackendImpl>(path_, max_bytes_, type_);
    auto* sql_cache_ptr = sql_cache.get();
    created_cache_ = std::move(sql_cache);
    sql_cache_ptr->Init(
        base::BindOnce(&CacheCreator::OnIOComplete, base::Unretained(this)));
    return;
  }
#endif  // ENABLE_DISK_CACHE_SQL_BACKEND

// Avoid references to blockfile functions on Android to reduce binary size.
#if BUILDFLAG(IS_ANDROID)
  FailAttempt();
#else
  auto cache = std::make_unique<disk_cache::BackendImpl>(
      path_, cleanup_tracker_.get(),
      /*cache_thread = */ nullptr, type_, net_log_);
  disk_cache::BackendImpl* new_cache = cache.get();
  created_cache_ = std::move(cache);
  if (!new_cache->SetMaxSize(max_bytes_)) {
    FailAttempt();
    return;
  }
  new_cache->Init(
      base::BindOnce(&CacheCreator::OnIOComplete, base::Unretained(this)));
#endif
}

void CacheCreator::FailAttempt() {
  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE, base::BindOnce(&CacheCreator::OnIOComplete,
                                base::Unretained(this), net::ERR_FAILED));
}

void CacheCreator::InitEncryptionAndRun() {
  if (cache_encryption_delegate_) {
    cache_encryption_delegate_->Init(base::BindOnce(
        &CacheCreator::OnEncryptionInitComplete, base::Unretained(this)));
    return;
  }
  Run();
}

void CacheCreator::TryCreateCleanupTrackerAndRun() {
  // Before creating a cache Backend, a BackendCleanupTracker object is needed
  // so there is a place to keep track of outstanding I/O even after the backend
  // object itself is destroyed, so that further use of the directory
  // doesn't race with those outstanding disk I/O ops.

  // This method's purpose it to grab exclusive ownership of a fresh
  // BackendCleanupTracker for the cache path, and then move on to Run(),
  // which will take care of creating the actual cache backend. It's possible
  // that something else is currently making use of the directory, in which
  // case BackendCleanupTracker::TryCreate will fail, but will just have
  // TryCreateCleanupTrackerAndRun run again at an opportune time to make
  // another attempt.

  // The resulting BackendCleanupTracker is stored into a scoped_refptr member
  // so that it's kept alive while |this| CacheCreator exists , so that in the
  // case Run() needs to retry Backend creation the same BackendCleanupTracker
  // is used for both attempts, and |post_cleanup_callback_| gets called after
  // the second try, not the first one.
  cleanup_tracker_ = disk_cache::BackendCleanupTracker::TryCreate(
      path_, base::BindOnce(base::IgnoreResult(
                                &CacheCreator::TryCreateCleanupTrackerAndRun),
                            base::Unretained(this)));
  if (!cleanup_tracker_) {
    return;
  }
  if (!post_cleanup_callback_.is_null()) {
    cleanup_tracker_->AddPostCleanupCallback(std::move(post_cleanup_callback_));
  }

  Run();
}

void CacheCreator::DoCallback(int net_error) {
  DCHECK_NE(net::ERR_IO_PENDING, net_error);
  disk_cache::BackendResult result;
  if (net_error == net::OK) {
    result = disk_cache::BackendResult::Make(std::move(created_cache_));
  } else {
    LOG(ERROR) << "Unable to create cache";
    result = disk_cache::BackendResult::MakeError(
        static_cast<net::Error>(net_error));
    created_cache_.reset();
  }
  std::move(callback_).Run(std::move(result));
  delete this;
}

// If the initialization of the cache fails, and |reset_handling| isn't set to
// kNeverReset, we will discard the whole cache and create a new one.
void CacheCreator::OnEncryptionInitComplete(net::Error result) {
  if (result == net::OK) {
    Run();
  } else {
    DoCallback(result);
  }
}

void CacheCreator::OnIOComplete(int result) {
  DCHECK_NE(result, net::ERR_IO_PENDING);
  if (result == net::OK ||
      reset_handling_ == disk_cache::ResetHandling::kNeverReset || retry_) {
    return DoCallback(result);
  }

  // We are supposed to try again, so delete the object and all files and do so.
  retry_ = true;
  created_cache_.reset();

  if (!file_operations_) {
    if (file_operations_factory_) {
      file_operations_ = file_operations_factory_->Create(
          base::SequencedTaskRunner::GetCurrentDefault());
    } else {
      file_operations_ = std::make_unique<disk_cache::TrivialFileOperations>();
    }
  }
  file_operations_->CleanupDirectory(
      path_, base::BindOnce(&CacheCreator::OnCacheCleanupComplete,
                            base::Unretained(this), result));
}

void CacheCreator::OnCacheCleanupComplete(int original_result,
                                          bool cleanup_result) {
  if (!cleanup_result) {
    // Cleaning up the cache directory fails, so this operation should be
    // considered failed.
    DCHECK_NE(original_result, net::OK);
    DCHECK_NE(original_result, net::ERR_IO_PENDING);
    DoCallback(original_result);
    return;
  }

  // The worker thread may be deleting files, but the original folder
  // is not there anymore... let's create a new set of files.
  Run();
}

class TrivialFileEnumerator final : public FileEnumerator {
 public:
  using FileEnumerationEntry =
      disk_cache::BackendFileOperations::FileEnumerationEntry;

  explicit TrivialFileEnumerator(const base::FilePath& path)
      : enumerator_(path) {}
  ~TrivialFileEnumerator() override = default;

  std::optional<FileEnumerationEntry> Next() override {
    return enumerator_.Next();
  }
  bool HasError() const override { return enumerator_.HasError(); }

 private:
  disk_cache::SimpleFileEnumerator enumerator_;
};

class UnboundTrivialFileOperations
    : public disk_cache::UnboundBackendFileOperations {
 public:
  std::unique_ptr<disk_cache::BackendFileOperations> Bind(
      scoped_refptr<base::SequencedTaskRunner> task_runner) override {
    return std::make_unique<disk_cache::TrivialFileOperations>();
  }
};

}  // namespace

namespace disk_cache {

BackendResult::BackendResult() = default;
BackendResult::~BackendResult() = default;
BackendResult::BackendResult(BackendResult&&) = default;
BackendResult& BackendResult::operator=(BackendResult&&) = default;

// static
BackendResult BackendResult::MakeError(net::Error error_in) {
  DCHECK_NE(error_in, net::OK);
  BackendResult result;
  result.net_error = error_in;
  return result;
}

// static
BackendResult BackendResult::Make(std::unique_ptr<Backend> backend_in) {
  DCHECK(backend_in);
  BackendResult result;
  result.net_error = net::OK;
  result.backend = std::move(backend_in);
  return result;
}

BackendResult CreateCacheBackendImpl(
    net::CacheType type,
    net::BackendType backend_type,
    scoped_refptr<BackendFileOperationsFactory> file_operations,
    const base::FilePath& path,
    int64_t max_bytes,
    ResetHandling reset_handling,
#if BUILDFLAG(IS_ANDROID)
    ApplicationStatusListenerGetter app_status_listener_getter,
#endif
    net::NetLog* net_log,
    net::CacheEncryptionDelegate* cache_encryption_delegate,
    base::OnceClosure post_cleanup_callback,
    BackendResultCallback callback) {
  DCHECK(!callback.is_null());

  if (type == net::MEMORY_CACHE) {
    std::unique_ptr<MemBackendImpl> mem_backend_impl =
        disk_cache::MemBackendImpl::CreateBackend(max_bytes, net_log);
    if (mem_backend_impl) {
      mem_backend_impl->SetPostCleanupCallback(
          std::move(post_cleanup_callback));
      return BackendResult::Make(std::move(mem_backend_impl));
    } else {
      if (!post_cleanup_callback.is_null()) {
        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, std::move(post_cleanup_callback));
      }
      return BackendResult::MakeError(net::ERR_FAILED);
    }
  }

  bool had_post_cleanup_callback = !post_cleanup_callback.is_null();
  CacheCreator* creator =
      new CacheCreator(path, reset_handling, max_bytes, type, backend_type,
                       std::move(file_operations),
#if BUILDFLAG(IS_ANDROID)
                       std::move(app_status_listener_getter),
#endif
                       net_log, std::move(cache_encryption_delegate),
                       std::move(post_cleanup_callback), std::move(callback));
  if (type == net::DISK_CACHE) {
    DCHECK(!had_post_cleanup_callback);
    creator->InitEncryptionAndRun();
  } else {
    creator->TryCreateCleanupTrackerAndRun();
  }
  return BackendResult::MakeError(net::ERR_IO_PENDING);
}

BackendResult CreateCacheBackend(
    net::CacheType type,
    net::BackendType backend_type,
    scoped_refptr<BackendFileOperationsFactory> file_operations,
    const base::FilePath& path,
    int64_t max_bytes,
    ResetHandling reset_handling,
    net::NetLog* net_log,
    net::CacheEncryptionDelegate* cache_encryption_delegate,
    BackendResultCallback callback) {
  return CreateCacheBackendImpl(type, backend_type, std::move(file_operations),
                                path, max_bytes, reset_handling,
#if BUILDFLAG(IS_ANDROID)
                                ApplicationStatusListenerGetter(),
#endif
                                net_log, std::move(cache_encryption_delegate),
                                base::OnceClosure(), std::move(callback));
}

#if BUILDFLAG(IS_ANDROID)
NET_EXPORT BackendResult
CreateCacheBackend(net::CacheType type,
                   net::BackendType backend_type,
                   scoped_refptr<BackendFileOperationsFactory> file_operations,
                   const base::FilePath& path,
                   int64_t max_bytes,
                   ResetHandling reset_handling,
                   net::NetLog* net_log,
                   net::CacheEncryptionDelegate* cache_encryption_delegate,
                   BackendResultCallback callback,
                   ApplicationStatusListenerGetter app_status_listener_getter) {
  return CreateCacheBackendImpl(type, backend_type, std::move(file_operations),
                                path, max_bytes, reset_handling,
                                std::move(app_status_listener_getter), net_log,
                                cache_encryption_delegate,
                                base::OnceClosure(), std::move(callback));
}
#endif

BackendResult CreateCacheBackend(
    net::CacheType type,
    net::BackendType backend_type,
    scoped_refptr<BackendFileOperationsFactory> file_operations,
    const base::FilePath& path,
    int64_t max_bytes,
    ResetHandling reset_handling,
    net::NetLog* net_log,
    net::CacheEncryptionDelegate* cache_encryption_delegate,
    base::OnceClosure post_cleanup_callback,
    BackendResultCallback callback) {
  return CreateCacheBackendImpl(type, backend_type, std::move(file_operations),
                                path, max_bytes, reset_handling,
#if BUILDFLAG(IS_ANDROID)
                                ApplicationStatusListenerGetter(),
#endif
                                net_log, cache_encryption_delegate,
                                std::move(post_cleanup_callback),
                                std::move(callback));
}

void FlushCacheThreadForTesting() {
  // For simple backend.
  base::ThreadPoolInstance::Get()->FlushForTesting();

  // Block backend.
  BackendImpl::FlushForTesting();
}

void FlushCacheThreadAsynchronouslyForTesting(base::OnceClosure callback) {
  auto repeating_callback = base::BarrierClosure(2, std::move(callback));

  // For simple backend.
  base::ThreadPoolInstance::Get()->FlushAsyncForTesting(  // IN-TEST
      base::BindPostTaskToCurrentDefault(repeating_callback));

  // Block backend.
  BackendImpl::FlushAsynchronouslyForTesting(repeating_callback);
}

int64_t Backend::CalculateSizeOfEntriesBetween(
    base::Time initial_time,
    base::Time end_time,
    Int64CompletionOnceCallback callback) {
  return net::ERR_NOT_IMPLEMENTED;
}

uint8_t Backend::GetEntryInMemoryData(const std::string& key) {
  return 0;
}

void Backend::OnBrowserIdle() {}

void Entry::SetEntryInMemoryData(uint8_t data) {}

EntryResult::EntryResult() = default;
EntryResult::~EntryResult() = default;

EntryResult::EntryResult(EntryResult&& other) {
  net_error_ = other.net_error_;
  entry_ = std::move(other.entry_);
  opened_ = other.opened_;

  other.net_error_ = net::ERR_FAILED;
  other.opened_ = false;
}

EntryResult& EntryResult::operator=(EntryResult&& other) {
  net_error_ = other.net_error_;
  entry_ = std::move(other.entry_);
  opened_ = other.opened_;

  other.net_error_ = net::ERR_FAILED;
  other.opened_ = false;
  return *this;
}

// static
EntryResult EntryResult::MakeOpened(Entry* new_entry) {
  DCHECK(new_entry);

  EntryResult result;
  result.net_error_ = net::OK;
  result.entry_.reset(new_entry);
  result.opened_ = true;
  return result;
}

// static
EntryResult EntryResult::MakeCreated(Entry* new_entry) {
  DCHECK(new_entry);

  EntryResult result;
  result.net_error_ = net::OK;
  result.entry_.reset(new_entry);
  result.opened_ = false;
  return result;
}

// static
EntryResult EntryResult::MakeError(net::Error status) {
  DCHECK_NE(status, net::OK);

  EntryResult result;
  result.net_error_ = status;
  return result;
}

Entry* EntryResult::ReleaseEntry() {
  Entry* ret = entry_.release();
  net_error_ = net::ERR_FAILED;
  opened_ = false;
  return ret;
}

TrivialFileOperations::TrivialFileOperations() {
  DETACH_FROM_SEQUENCE(sequence_checker_);
}

TrivialFileOperations::~TrivialFileOperations() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

bool TrivialFileOperations::CreateDirectory(const base::FilePath& path) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
  DCHECK(bound_);
#endif

  // This is needed for some unittests.
  if (path.empty()) {
    return false;
  }

  DCHECK(path.IsAbsolute());

  bool result = base::CreateDirectory(path);
  return result;
}

bool TrivialFileOperations::PathExists(const base::FilePath& path) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
  DCHECK(bound_);
#endif

  // This is needed for some unittests.
  if (path.empty()) {
    return false;
  }

  DCHECK(path.IsAbsolute());

  bool result = base::PathExists(path);
  return result;
}

bool TrivialFileOperations::DirectoryExists(const base::FilePath& path) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(path.IsAbsolute());
#if DCHECK_IS_ON()
  DCHECK(bound_);
#endif

  bool result = base::DirectoryExists(path);
  return result;
}

std::unique_ptr<CacheFile> TrivialFileOperations::OpenFile(
    const base::FilePath& path,
    uint32_t flags) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(path.IsAbsolute());
#if DCHECK_IS_ON()
  DCHECK(bound_);
#endif

  base::File file(path, flags);
  return std::make_unique<BasicCacheFile>(std::move(file));
}

bool TrivialFileOperations::DeleteFile(const base::FilePath& path,
                                       DeleteFileMode mode) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(path.IsAbsolute());
#if DCHECK_IS_ON()
  DCHECK(bound_);
#endif

  bool result = false;
  switch (mode) {
    case DeleteFileMode::kDefault:
      result = base::DeleteFile(path);
      break;
    case DeleteFileMode::kEnsureImmediateAvailability:
      result = disk_cache::simple_util::SimpleCacheDeleteFile(path);
      break;
  }
  return result;
}

bool TrivialFileOperations::ReplaceFile(const base::FilePath& from_path,
                                        const base::FilePath& to_path,
                                        base::File::Error* error) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(from_path.IsAbsolute());
  DCHECK(to_path.IsAbsolute());
#if DCHECK_IS_ON()
  DCHECK(bound_);
#endif

  return base::ReplaceFile(from_path, to_path, error);
}

std::optional<base::File::Info> TrivialFileOperations::GetFileInfo(
    const base::FilePath& path) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(path.IsAbsolute());
#if DCHECK_IS_ON()
  DCHECK(bound_);
#endif

  base::File::Info file_info;
  if (!base::GetFileInfo(path, &file_info)) {
    return std::nullopt;
  }
  return file_info;
}

std::unique_ptr<FileEnumerator> TrivialFileOperations::EnumerateFiles(
    const base::FilePath& path) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(path.IsAbsolute());
#if DCHECK_IS_ON()
  DCHECK(bound_);
#endif
  return std::make_unique<TrivialFileEnumerator>(path);
}

void TrivialFileOperations::CleanupDirectory(
    const base::FilePath& path,
    base::OnceCallback<void(bool)> callback) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // This is needed for some unittests.
  if (path.empty()) {
    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE, base::BindOnce(std::move(callback), false));
    return;
  }

  DCHECK(path.IsAbsolute());
#if DCHECK_IS_ON()
  DCHECK(bound_);
#endif

  disk_cache::CleanupDirectory(path, std::move(callback));
}

std::unique_ptr<UnboundBackendFileOperations> TrivialFileOperations::Unbind() {
#if DCHECK_IS_ON()
  DCHECK(bound_);
  bound_ = false;
#endif
  return std::make_unique<UnboundTrivialFileOperations>();
}

bool TrivialFileOperations::IsEncrypted() const {
  return false;
}

TrivialFileOperationsFactory::TrivialFileOperationsFactory() = default;
TrivialFileOperationsFactory::~TrivialFileOperationsFactory() = default;

std::unique_ptr<BackendFileOperations> TrivialFileOperationsFactory::Create(
    scoped_refptr<base::SequencedTaskRunner> task_runner) {
  return std::make_unique<TrivialFileOperations>();
}

std::unique_ptr<UnboundBackendFileOperations>
TrivialFileOperationsFactory::CreateUnbound() {
  return std::make_unique<UnboundTrivialFileOperations>();
}

}  // namespace disk_cache
