// Copyright (c) 2012 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 "net/http/mock_http_cache.h"

#include <algorithm>
#include <limits>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/net_errors.h"
#include "net/http/http_cache_writers.h"
#include "starboard/character.h"
#include "starboard/memory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

// During testing, we are going to limit the size of a cache entry to this many
// bytes using DCHECKs in order to prevent a test from causing unbounded memory
// growth. In practice cache entry shouldn't come anywhere near this limit for
// tests that use the mock cache. If they do, that's likely a problem with the
// test. If a test requires using massive cache entries, they should use a real
// cache backend instead.
const int kMaxMockCacheEntrySize = 100 * 1000 * 1000;

// We can override the test mode for a given operation by setting this global
// variable.
int g_test_mode = 0;

int GetTestModeForEntry(const std::string& key) {
  // 'key' is prefixed with an identifier if it corresponds to a cached POST.
  // Skip past that to locate the actual URL.
  //
  // TODO(darin): It breaks the abstraction a bit that we assume 'key' is an
  // URL corresponding to a registered MockTransaction.  It would be good to
  // have another way to access the test_mode.
  GURL url;
  if (SbCharacterIsDigit(key[0])) {
    size_t slash = key.find('/');
    DCHECK(slash != std::string::npos);
    url = GURL(key.substr(slash + 1));
  } else {
    url = GURL(key);
  }
  const MockTransaction* t = FindMockTransaction(url);
  DCHECK(t);
  return t->test_mode;
}

}  // namespace

//-----------------------------------------------------------------------------

struct MockDiskEntry::CallbackInfo {
  scoped_refptr<MockDiskEntry> entry;
  net::CompletionOnceCallback callback;
  int result;
};

MockDiskEntry::MockDiskEntry(const std::string& key)
    : key_(key),
      in_memory_data_(0),
      doomed_(false),
      sparse_(false),
      fail_requests_(false),
      fail_sparse_requests_(false),
      busy_(false),
      delayed_(false),
      cancel_(false),
      defer_op_(DEFER_NONE),
      resume_return_code_(0) {
  test_mode_ = GetTestModeForEntry(key);
}

void MockDiskEntry::Doom() {
  doomed_ = true;
}

void MockDiskEntry::Close() {
  Release();
}

std::string MockDiskEntry::GetKey() const {
  return key_;
}

base::Time MockDiskEntry::GetLastUsed() const {
  return base::Time::Now();
}

base::Time MockDiskEntry::GetLastModified() const {
  return base::Time::Now();
}

int32_t MockDiskEntry::GetDataSize(int index) const {
  DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
  return static_cast<int32_t>(data_[index].size());
}

int MockDiskEntry::ReadData(int index,
                            int offset,
                            IOBuffer* buf,
                            int buf_len,
                            CompletionOnceCallback callback) {
  DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
  DCHECK(!callback.is_null());

  if (fail_requests_)
    return ERR_CACHE_READ_FAILURE;

  if (offset < 0 || offset > static_cast<int>(data_[index].size()))
    return ERR_FAILED;
  if (static_cast<size_t>(offset) == data_[index].size())
    return 0;

  int num = std::min(buf_len, static_cast<int>(data_[index].size()) - offset);
  SbMemoryCopy(buf->data(), &data_[index][offset], num);

  if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
    return num;

  // Pause and resume.
  if (defer_op_ == DEFER_READ) {
    defer_op_ = DEFER_NONE;
    resume_callback_ = std::move(callback);
    resume_return_code_ = num;
    return ERR_IO_PENDING;
  }

  CallbackLater(std::move(callback), num);
  return ERR_IO_PENDING;
}

void MockDiskEntry::ResumeDiskEntryOperation() {
  DCHECK(!resume_callback_.is_null());
  CallbackLater(std::move(resume_callback_), resume_return_code_);
  resume_return_code_ = 0;
}

int MockDiskEntry::WriteData(int index,
                             int offset,
                             IOBuffer* buf,
                             int buf_len,
                             CompletionOnceCallback callback,
                             bool truncate) {
  DCHECK(index >= 0 && index < kNumCacheEntryDataIndices);
  DCHECK(!callback.is_null());
  DCHECK(truncate);

  if (fail_requests_) {
    CallbackLater(std::move(callback), ERR_CACHE_READ_FAILURE);
    return ERR_IO_PENDING;
  }

  if (offset < 0 || offset > static_cast<int>(data_[index].size()))
    return ERR_FAILED;

  DCHECK_LT(offset + buf_len, kMaxMockCacheEntrySize);
  data_[index].resize(offset + buf_len);
  if (buf_len)
    SbMemoryCopy(&data_[index][offset], buf->data(), buf_len);

  if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE)
    return buf_len;

  if (defer_op_ == DEFER_WRITE) {
    defer_op_ = DEFER_NONE;
    resume_callback_ = std::move(callback);
    resume_return_code_ = buf_len;
    return ERR_IO_PENDING;
  }

  CallbackLater(std::move(callback), buf_len);
  return ERR_IO_PENDING;
}

int MockDiskEntry::ReadSparseData(int64_t offset,
                                  IOBuffer* buf,
                                  int buf_len,
                                  CompletionOnceCallback callback) {
  DCHECK(!callback.is_null());
  if (fail_sparse_requests_)
    return ERR_NOT_IMPLEMENTED;
  if (!sparse_ || busy_ || cancel_)
    return ERR_CACHE_OPERATION_NOT_SUPPORTED;
  if (offset < 0)
    return ERR_FAILED;

  if (fail_requests_)
    return ERR_CACHE_READ_FAILURE;

  DCHECK(offset < std::numeric_limits<int32_t>::max());
  int real_offset = static_cast<int>(offset);
  if (!buf_len)
    return 0;

  int num = std::min(static_cast<int>(data_[1].size()) - real_offset,
                     buf_len);
  SbMemoryCopy(buf->data(), &data_[1][real_offset], num);

  if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
    return num;

  CallbackLater(std::move(callback), num);
  busy_ = true;
  delayed_ = false;
  return ERR_IO_PENDING;
}

int MockDiskEntry::WriteSparseData(int64_t offset,
                                   IOBuffer* buf,
                                   int buf_len,
                                   CompletionOnceCallback callback) {
  DCHECK(!callback.is_null());
  if (fail_sparse_requests_)
    return ERR_NOT_IMPLEMENTED;
  if (busy_ || cancel_)
    return ERR_CACHE_OPERATION_NOT_SUPPORTED;
  if (!sparse_) {
    if (data_[1].size())
      return ERR_CACHE_OPERATION_NOT_SUPPORTED;
    sparse_ = true;
  }
  if (offset < 0)
    return ERR_FAILED;
  if (!buf_len)
    return 0;

  if (fail_requests_)
    return ERR_CACHE_READ_FAILURE;

  DCHECK(offset < std::numeric_limits<int32_t>::max());
  int real_offset = static_cast<int>(offset);

  if (static_cast<int>(data_[1].size()) < real_offset + buf_len) {
    DCHECK_LT(real_offset + buf_len, kMaxMockCacheEntrySize);
    data_[1].resize(real_offset + buf_len);
  }

  SbMemoryCopy(&data_[1][real_offset], buf->data(), buf_len);
  if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE)
    return buf_len;

  CallbackLater(std::move(callback), buf_len);
  return ERR_IO_PENDING;
}

int MockDiskEntry::GetAvailableRange(int64_t offset,
                                     int len,
                                     int64_t* start,
                                     CompletionOnceCallback callback) {
  DCHECK(!callback.is_null());
  if (!sparse_ || busy_ || cancel_)
    return ERR_CACHE_OPERATION_NOT_SUPPORTED;
  if (offset < 0)
    return ERR_FAILED;

  if (fail_requests_)
    return ERR_CACHE_READ_FAILURE;

  *start = offset;
  DCHECK(offset < std::numeric_limits<int32_t>::max());
  int real_offset = static_cast<int>(offset);
  if (static_cast<int>(data_[1].size()) < real_offset)
    return 0;

  int num = std::min(static_cast<int>(data_[1].size()) - real_offset, len);
  int count = 0;
  for (; num > 0; num--, real_offset++) {
    if (!count) {
      if (data_[1][real_offset]) {
        count++;
        *start = real_offset;
      }
    } else {
      if (!data_[1][real_offset])
        break;
      count++;
    }
  }
  if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_WRITE)
    return count;

  CallbackLater(std::move(callback), count);
  return ERR_IO_PENDING;
}

bool MockDiskEntry::CouldBeSparse() const {
  if (fail_sparse_requests_)
    return false;
  return sparse_;
}

void MockDiskEntry::CancelSparseIO() {
  cancel_ = true;
}

net::Error MockDiskEntry::ReadyForSparseIO(CompletionOnceCallback callback) {
  if (fail_sparse_requests_)
    return ERR_NOT_IMPLEMENTED;
  if (!cancel_)
    return OK;

  cancel_ = false;
  DCHECK(!callback.is_null());
  if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
    return OK;

  // The pending operation is already in the message loop (and hopefully
  // already in the second pass).  Just notify the caller that it finished.
  CallbackLater(std::move(callback), 0);
  return ERR_IO_PENDING;
}

void MockDiskEntry::SetLastUsedTimeForTest(base::Time time) {
  NOTREACHED();
}

// If |value| is true, don't deliver any completion callbacks until called
// again with |value| set to false.  Caution: remember to enable callbacks
// again or all subsequent tests will fail.
// Static.
void MockDiskEntry::IgnoreCallbacks(bool value) {
  if (ignore_callbacks_ == value)
    return;
  ignore_callbacks_ = value;
  if (!value)
    StoreAndDeliverCallbacks(false, NULL, CompletionOnceCallback(), 0);
}

MockDiskEntry::~MockDiskEntry() = default;

// Unlike the callbacks for MockHttpTransaction, we want this one to run even
// if the consumer called Close on the MockDiskEntry.  We achieve that by
// leveraging the fact that this class is reference counted.
void MockDiskEntry::CallbackLater(CompletionOnceCallback callback, int result) {
  if (ignore_callbacks_)
    return StoreAndDeliverCallbacks(true, this, std::move(callback), result);
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&MockDiskEntry::RunCallback, this,
                                std::move(callback), result));
}

void MockDiskEntry::RunCallback(CompletionOnceCallback callback, int result) {
  if (busy_) {
    // This is kind of hacky, but controlling the behavior of just this entry
    // from a test is sort of complicated.  What we really want to do is
    // delay the delivery of a sparse IO operation a little more so that the
    // request start operation (async) will finish without seeing the end of
    // this operation (already posted to the message loop)... and without
    // just delaying for n mS (which may cause trouble with slow bots).  So
    // we re-post this operation (all async sparse IO operations will take two
    // trips through the message loop instead of one).
    if (!delayed_) {
      delayed_ = true;
      return CallbackLater(std::move(callback), result);
    }
  }
  busy_ = false;
  std::move(callback).Run(result);
}

// When |store| is true, stores the callback to be delivered later; otherwise
// delivers any callback previously stored.
// Static.
void MockDiskEntry::StoreAndDeliverCallbacks(bool store,
                                             MockDiskEntry* entry,
                                             CompletionOnceCallback callback,
                                             int result) {
  static std::vector<CallbackInfo> callback_list;
  if (store) {
    CallbackInfo c = {entry, std::move(callback), result};
    callback_list.push_back(std::move(c));
  } else {
    for (size_t i = 0; i < callback_list.size(); i++) {
      CallbackInfo& c = callback_list[i];
      c.entry->CallbackLater(std::move(c.callback), c.result);
    }
    callback_list.clear();
  }
}

// Statics.
bool MockDiskEntry::ignore_callbacks_ = false;

//-----------------------------------------------------------------------------

MockDiskCache::MockDiskCache()
    : open_count_(0),
      create_count_(0),
      doomed_count_(0),
      fail_requests_(false),
      soft_failures_(false),
      double_create_check_(true),
      fail_sparse_requests_(false),
      support_in_memory_entry_data_(true),
      defer_op_(MockDiskEntry::DEFER_NONE),
      resume_return_code_(0) {}

MockDiskCache::~MockDiskCache() {
  ReleaseAll();
}

CacheType MockDiskCache::GetCacheType() const {
  return DISK_CACHE;
}

int32_t MockDiskCache::GetEntryCount() const {
  return static_cast<int32_t>(entries_.size());
}

net::Error MockDiskCache::OpenEntry(const std::string& key,
                                    net::RequestPriority request_priority,
                                    disk_cache::Entry** entry,
                                    CompletionOnceCallback callback) {
  DCHECK(!callback.is_null());
  if (fail_requests_)
    return ERR_CACHE_OPEN_FAILURE;

  auto it = entries_.find(key);
  if (it == entries_.end())
    return ERR_CACHE_OPEN_FAILURE;

  if (it->second->is_doomed()) {
    it->second->Release();
    entries_.erase(it);
    return ERR_CACHE_OPEN_FAILURE;
  }

  open_count_++;

  it->second->AddRef();
  *entry = it->second;

  if (soft_failures_)
    it->second->set_fail_requests();

  if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
    return OK;

  CallbackLater(std::move(callback), OK);
  return ERR_IO_PENDING;
}

net::Error MockDiskCache::CreateEntry(const std::string& key,
                                      net::RequestPriority request_priority,
                                      disk_cache::Entry** entry,
                                      CompletionOnceCallback callback) {
  DCHECK(!callback.is_null());
  if (fail_requests_)
    return ERR_CACHE_CREATE_FAILURE;

  auto it = entries_.find(key);
  if (it != entries_.end()) {
    if (!it->second->is_doomed()) {
      if (double_create_check_)
        NOTREACHED();
      else
        return ERR_CACHE_CREATE_FAILURE;
    }
    it->second->Release();
    entries_.erase(it);
  }

  create_count_++;

  MockDiskEntry* new_entry = new MockDiskEntry(key);

  new_entry->AddRef();
  entries_[key] = new_entry;

  new_entry->AddRef();
  *entry = new_entry;

  if (soft_failures_)
    new_entry->set_fail_requests();

  if (fail_sparse_requests_)
    new_entry->set_fail_sparse_requests();

  if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
    return OK;

  // Pause and resume.
  if (defer_op_ == MockDiskEntry::DEFER_CREATE) {
    defer_op_ = MockDiskEntry::DEFER_NONE;
    resume_callback_ = std::move(callback);
    resume_return_code_ = OK;
    return ERR_IO_PENDING;
  }

  CallbackLater(std::move(callback), OK);
  return ERR_IO_PENDING;
}

net::Error MockDiskCache::DoomEntry(const std::string& key,
                                    net::RequestPriority request_priority,
                                    CompletionOnceCallback callback) {
  DCHECK(!callback.is_null());
  auto it = entries_.find(key);
  if (it != entries_.end()) {
    it->second->Release();
    entries_.erase(it);
    doomed_count_++;
  }

  if (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
    return OK;

  CallbackLater(std::move(callback), OK);
  return ERR_IO_PENDING;
}

net::Error MockDiskCache::DoomAllEntries(CompletionOnceCallback callback) {
  return ERR_NOT_IMPLEMENTED;
}

net::Error MockDiskCache::DoomEntriesBetween(const base::Time initial_time,
                                             const base::Time end_time,
                                             CompletionOnceCallback callback) {
  return ERR_NOT_IMPLEMENTED;
}

net::Error MockDiskCache::DoomEntriesSince(const base::Time initial_time,
                                           CompletionOnceCallback callback) {
  return ERR_NOT_IMPLEMENTED;
}

int64_t MockDiskCache::CalculateSizeOfAllEntries(
    Int64CompletionOnceCallback callback) {
  return ERR_NOT_IMPLEMENTED;
}

class MockDiskCache::NotImplementedIterator : public Iterator {
 public:
  net::Error OpenNextEntry(disk_cache::Entry** next_entry,
                           CompletionOnceCallback callback) override {
    return ERR_NOT_IMPLEMENTED;
  }
};

std::unique_ptr<disk_cache::Backend::Iterator> MockDiskCache::CreateIterator() {
  return std::unique_ptr<Iterator>(new NotImplementedIterator());
}

void MockDiskCache::GetStats(base::StringPairs* stats) {
}

void MockDiskCache::OnExternalCacheHit(const std::string& key) {
}

size_t MockDiskCache::DumpMemoryStats(
    base::trace_event::ProcessMemoryDump* pmd,
    const std::string& parent_absolute_name) const {
  return 0u;
}

uint8_t MockDiskCache::GetEntryInMemoryData(const std::string& key) {
  if (!support_in_memory_entry_data_)
    return 0;

  auto it = entries_.find(key);
  if (it != entries_.end())
    return it->second->in_memory_data();
  return 0;
}

void MockDiskCache::SetEntryInMemoryData(const std::string& key, uint8_t data) {
  auto it = entries_.find(key);
  if (it != entries_.end())
    it->second->set_in_memory_data(data);
}

void MockDiskCache::ReleaseAll() {
  for (auto entry : entries_)
    entry.second->Release();
  entries_.clear();
}

void MockDiskCache::CallbackLater(CompletionOnceCallback callback, int result) {
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(std::move(callback), result));
}

bool MockDiskCache::IsDiskEntryDoomed(const std::string& key) {
  auto it = entries_.find(key);
  if (it != entries_.end())
    return it->second->is_doomed();

  return false;
}

void MockDiskCache::ResumeCacheOperation() {
  DCHECK(!resume_callback_.is_null());
  CallbackLater(std::move(resume_callback_), resume_return_code_);
  resume_return_code_ = 0;
}

scoped_refptr<MockDiskEntry> MockDiskCache::GetDiskEntryRef(
    const std::string& key) {
  auto it = entries_.find(key);
  if (it == entries_.end())
    return nullptr;
  return it->second;
}

//-----------------------------------------------------------------------------

int MockBackendFactory::CreateBackend(
    NetLog* net_log,
    std::unique_ptr<disk_cache::Backend>* backend,
    CompletionOnceCallback callback) {
  backend->reset(new MockDiskCache());
  return OK;
}

//-----------------------------------------------------------------------------

MockHttpCache::MockHttpCache() : MockHttpCache(false) {}

MockHttpCache::MockHttpCache(
    std::unique_ptr<HttpCache::BackendFactory> disk_cache_factory)
    : MockHttpCache(std::move(disk_cache_factory), false) {}

MockHttpCache::MockHttpCache(bool is_main_cache)
    : MockHttpCache(std::make_unique<MockBackendFactory>(), is_main_cache) {}

MockHttpCache::MockHttpCache(
    std::unique_ptr<HttpCache::BackendFactory> disk_cache_factory,
    bool is_main_cache)
    : http_cache_(std::make_unique<MockNetworkLayer>(),
                  std::move(disk_cache_factory),
                  is_main_cache) {}

disk_cache::Backend* MockHttpCache::backend() {
  TestCompletionCallback cb;
  disk_cache::Backend* backend;
  int rv = http_cache_.GetBackend(&backend, cb.callback());
  rv = cb.GetResult(rv);
  return (rv == OK) ? backend : NULL;
}

MockDiskCache* MockHttpCache::disk_cache() {
  return static_cast<MockDiskCache*>(backend());
}

int MockHttpCache::CreateTransaction(std::unique_ptr<HttpTransaction>* trans) {
  return http_cache_.CreateTransaction(DEFAULT_PRIORITY, trans);
}

void MockHttpCache::SimulateCacheLockTimeout() {
  http_cache_.SimulateCacheLockTimeoutForTesting();
}

void MockHttpCache::SimulateCacheLockTimeoutAfterHeaders() {
  http_cache_.SimulateCacheLockTimeoutAfterHeadersForTesting();
}

void MockHttpCache::FailConditionalizations() {
  http_cache_.FailConditionalizationForTest();
}

bool MockHttpCache::ReadResponseInfo(disk_cache::Entry* disk_entry,
                                     HttpResponseInfo* response_info,
                                     bool* response_truncated) {
  int size = disk_entry->GetDataSize(0);

  TestCompletionCallback cb;
  scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(size);
  int rv = disk_entry->ReadData(0, 0, buffer.get(), size, cb.callback());
  rv = cb.GetResult(rv);
  EXPECT_EQ(size, rv);

  return HttpCache::ParseResponseInfo(buffer->data(), size, response_info,
                                      response_truncated);
}

bool MockHttpCache::WriteResponseInfo(disk_cache::Entry* disk_entry,
                                      const HttpResponseInfo* response_info,
                                      bool skip_transient_headers,
                                      bool response_truncated) {
  base::Pickle pickle;
  response_info->Persist(
      &pickle, skip_transient_headers, response_truncated);

  TestCompletionCallback cb;
  scoped_refptr<WrappedIOBuffer> data = base::MakeRefCounted<WrappedIOBuffer>(
      reinterpret_cast<const char*>(pickle.data()));
  int len = static_cast<int>(pickle.size());

  int rv = disk_entry->WriteData(0, 0, data.get(), len, cb.callback(), true);
  rv = cb.GetResult(rv);
  return (rv == len);
}

bool MockHttpCache::OpenBackendEntry(const std::string& key,
                                     disk_cache::Entry** entry) {
  TestCompletionCallback cb;
  int rv = backend()->OpenEntry(key, net::HIGHEST, entry, cb.callback());
  return (cb.GetResult(rv) == OK);
}

bool MockHttpCache::CreateBackendEntry(const std::string& key,
                                       disk_cache::Entry** entry,
                                       NetLog* net_log) {
  TestCompletionCallback cb;
  int rv = backend()->CreateEntry(key, net::HIGHEST, entry, cb.callback());
  return (cb.GetResult(rv) == OK);
}

// Static.
int MockHttpCache::GetTestMode(int test_mode) {
  if (!g_test_mode)
    return test_mode;

  return g_test_mode;
}

// Static.
void MockHttpCache::SetTestMode(int test_mode) {
  g_test_mode = test_mode;
}

bool MockHttpCache::IsWriterPresent(const std::string& key) {
  HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key);
  return entry && entry->writers && !entry->writers->IsEmpty();
}

bool MockHttpCache::IsHeadersTransactionPresent(const std::string& key) {
  HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key);
  return entry && entry->headers_transaction;
}

int MockHttpCache::GetCountReaders(const std::string& key) {
  HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key);
  return entry ? entry->readers.size() : 0;
}

int MockHttpCache::GetCountAddToEntryQueue(const std::string& key) {
  HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key);
  return entry ? entry->add_to_entry_queue.size() : 0;
}

int MockHttpCache::GetCountDoneHeadersQueue(const std::string& key) {
  HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key);
  return entry ? entry->done_headers_queue.size() : 0;
}

int MockHttpCache::GetCountWriterTransactions(const std::string& key) {
  HttpCache::ActiveEntry* entry = http_cache_.FindActiveEntry(key);
  return entry && entry->writers ? entry->writers->GetTransactionsCount() : 0;
}

//-----------------------------------------------------------------------------

net::Error MockDiskCacheNoCB::CreateEntry(const std::string& key,
                                          net::RequestPriority request_priority,
                                          disk_cache::Entry** entry,
                                          CompletionOnceCallback callback) {
  return ERR_IO_PENDING;
}

//-----------------------------------------------------------------------------

int MockBackendNoCbFactory::CreateBackend(
    NetLog* net_log,
    std::unique_ptr<disk_cache::Backend>* backend,
    CompletionOnceCallback callback) {
  backend->reset(new MockDiskCacheNoCB());
  return OK;
}

//-----------------------------------------------------------------------------

MockBlockingBackendFactory::MockBlockingBackendFactory()
    : backend_(NULL),
      block_(true),
      fail_(false) {
}

MockBlockingBackendFactory::~MockBlockingBackendFactory() = default;

int MockBlockingBackendFactory::CreateBackend(
    NetLog* net_log,
    std::unique_ptr<disk_cache::Backend>* backend,
    CompletionOnceCallback callback) {
  if (!block_) {
    if (!fail_)
      backend->reset(new MockDiskCache());
    return Result();
  }

  backend_ =  backend;
  callback_ = std::move(callback);
  return ERR_IO_PENDING;
}

void MockBlockingBackendFactory::FinishCreation() {
  block_ = false;
  if (!callback_.is_null()) {
    if (!fail_)
      backend_->reset(new MockDiskCache());
    // Running the callback might delete |this|.
    base::ResetAndReturn(&callback_).Run(Result());
  }
}

}  // namespace net
