// 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 "base/bind.h"
#include "base/message_loop.h"
#include "net/base/completion_callback.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// 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 (isdigit(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;
}

void CallbackForwader(const net::CompletionCallback& callback, int result) {
  callback.Run(result);
}

}  // namespace

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

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

MockDiskEntry::MockDiskEntry()
    : test_mode_(0), doomed_(false), sparse_(false),
      fail_requests_(false), busy_(false), delayed_(false) {
}

MockDiskEntry::MockDiskEntry(const std::string& key)
    : key_(key), doomed_(false), sparse_(false),
      fail_requests_(false), busy_(false), delayed_(false) {
  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::FromInternalValue(0);
}

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

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

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

  if (fail_requests_)
    return net::ERR_CACHE_READ_FAILURE;

  if (offset < 0 || offset > static_cast<int>(data_[index].size()))
    return net::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);
  memcpy(buf->data(), &data_[index][offset], num);

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

  CallbackLater(callback, num);
  return net::ERR_IO_PENDING;
}

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

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

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

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

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

  CallbackLater(callback, buf_len);
  return net::ERR_IO_PENDING;
}

int MockDiskEntry::ReadSparseData(int64 offset, net::IOBuffer* buf, int buf_len,
                                  const net::CompletionCallback& callback) {
  DCHECK(!callback.is_null());
  if (!sparse_ || busy_)
    return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
  if (offset < 0)
    return net::ERR_FAILED;

  if (fail_requests_)
    return net::ERR_CACHE_READ_FAILURE;

  DCHECK(offset < kint32max);
  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);
  memcpy(buf->data(), &data_[1][real_offset], num);

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

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

int MockDiskEntry::WriteSparseData(int64 offset, net::IOBuffer* buf,
                                   int buf_len,
                                   const net::CompletionCallback& callback) {
  DCHECK(!callback.is_null());
  if (busy_)
    return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
  if (!sparse_) {
    if (data_[1].size())
      return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
    sparse_ = true;
  }
  if (offset < 0)
    return net::ERR_FAILED;
  if (!buf_len)
    return 0;

  if (fail_requests_)
    return net::ERR_CACHE_READ_FAILURE;

  DCHECK(offset < kint32max);
  int real_offset = static_cast<int>(offset);

  if (static_cast<int>(data_[1].size()) < real_offset + buf_len)
    data_[1].resize(real_offset + buf_len);

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

  CallbackLater(callback, buf_len);
  return net::ERR_IO_PENDING;
}

int MockDiskEntry::GetAvailableRange(int64 offset, int len, int64* start,
                                     const net::CompletionCallback& callback) {
  DCHECK(!callback.is_null());
  if (!sparse_ || busy_)
    return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
  if (offset < 0)
    return net::ERR_FAILED;

  if (fail_requests_)
    return net::ERR_CACHE_READ_FAILURE;

  *start = offset;
  DCHECK(offset < kint32max);
  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(callback, count);
  return net::ERR_IO_PENDING;
}

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

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

int MockDiskEntry::ReadyForSparseIO(const net::CompletionCallback& callback) {
  if (!cancel_)
    return net::OK;

  cancel_ = false;
  DCHECK(!callback.is_null());
  if (MockHttpCache::GetTestMode(test_mode_) & TEST_MODE_SYNC_CACHE_READ)
    return net::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(callback, 0);
  return net::ERR_IO_PENDING;
}

// 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, net::CompletionCallback(), 0);
}

MockDiskEntry::~MockDiskEntry() {
}

// 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(const net::CompletionCallback& callback,
                                  int result) {
  if (ignore_callbacks_)
    return StoreAndDeliverCallbacks(true, this, callback, result);
  MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
      &MockDiskEntry::RunCallback, this, callback, result));
}

void MockDiskEntry::RunCallback(
    const net::CompletionCallback& 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(callback, result);
    }
  }
  busy_ = false;
  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, const net::CompletionCallback& callback,
    int result) {
  static std::vector<CallbackInfo> callback_list;
  if (store) {
    CallbackInfo c = {entry, callback, result};
    callback_list.push_back(c);
  } else {
    for (size_t i = 0; i < callback_list.size(); i++) {
      CallbackInfo& c = callback_list[i];
      c.entry->CallbackLater(c.callback, c.result);
    }
    callback_list.clear();
  }
}

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

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

MockDiskCache::MockDiskCache()
    : open_count_(0), create_count_(0), fail_requests_(false),
      soft_failures_(false), double_create_check_(true) {
}

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

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

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

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

  EntryMap::iterator it = entries_.find(key);
  if (it == entries_.end())
    return net::ERR_CACHE_OPEN_FAILURE;

  if (it->second->is_doomed()) {
    it->second->Release();
    entries_.erase(it);
    return net::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 net::OK;

  CallbackLater(callback, net::OK);
  return net::ERR_IO_PENDING;
}

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

  EntryMap::iterator it = entries_.find(key);
  if (it != entries_.end()) {
    if (!it->second->is_doomed()) {
      if (double_create_check_)
        NOTREACHED();
      else
        return net::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 (GetTestModeForEntry(key) & TEST_MODE_SYNC_CACHE_START)
    return net::OK;

  CallbackLater(callback, net::OK);
  return net::ERR_IO_PENDING;
}

int MockDiskCache::DoomEntry(const std::string& key,
                             const net::CompletionCallback& callback) {
  DCHECK(!callback.is_null());
  EntryMap::iterator it = entries_.find(key);
  if (it != entries_.end()) {
    it->second->Release();
    entries_.erase(it);
  }

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

  CallbackLater(callback, net::OK);
  return net::ERR_IO_PENDING;
}

int MockDiskCache::DoomAllEntries(const net::CompletionCallback& callback) {
  return net::ERR_NOT_IMPLEMENTED;
}

int MockDiskCache::DoomEntriesBetween(const base::Time initial_time,
                                      const base::Time end_time,
                                      const net::CompletionCallback& callback) {
  return net::ERR_NOT_IMPLEMENTED;
}

int MockDiskCache::DoomEntriesSince(const base::Time initial_time,
                                    const net::CompletionCallback& callback) {
  return net::ERR_NOT_IMPLEMENTED;
}

int MockDiskCache::OpenNextEntry(void** iter, disk_cache::Entry** next_entry,
                                 const net::CompletionCallback& callback) {
  return net::ERR_NOT_IMPLEMENTED;
}

void MockDiskCache::EndEnumeration(void** iter) {
}

void MockDiskCache::GetStats(
    std::vector<std::pair<std::string, std::string> >* stats) {
}

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

void MockDiskCache::ReleaseAll() {
  EntryMap::iterator it = entries_.begin();
  for (; it != entries_.end(); ++it)
    it->second->Release();
  entries_.clear();
}

void MockDiskCache::CallbackLater(const net::CompletionCallback& callback,
                                  int result) {
  MessageLoop::current()->PostTask(
      FROM_HERE, base::Bind(&CallbackForwader, callback, result));
}

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

int MockBackendFactory::CreateBackend(net::NetLog* net_log,
                                      disk_cache::Backend** backend,
                                      const net::CompletionCallback& callback) {
  *backend = new MockDiskCache();
  return net::OK;
}

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

MockHttpCache::MockHttpCache()
    : http_cache_(new MockNetworkLayer(), NULL, new MockBackendFactory()) {
}

MockHttpCache::MockHttpCache(net::HttpCache::BackendFactory* disk_cache_factory)
    : http_cache_(new MockNetworkLayer(), NULL, disk_cache_factory) {
}

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

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

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

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

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

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

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

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

bool MockHttpCache::CreateBackendEntry(const std::string& key,
                                       disk_cache::Entry** entry,
                                       net::NetLog* net_log) {
  net::TestCompletionCallback cb;
  if (!disk_cache()) return false;
  int rv = disk_cache()->CreateEntry(key, entry, cb.callback());
  return (cb.GetResult(rv) == net::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;
}

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

int MockDiskCacheNoCB::CreateEntry(const std::string& key,
                                   disk_cache::Entry** entry,
                                   const net::CompletionCallback& callback) {
  return net::ERR_IO_PENDING;
}

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

int MockBackendNoCbFactory::CreateBackend(
    net::NetLog* net_log, disk_cache::Backend** backend,
    const net::CompletionCallback& callback) {
  *backend = new MockDiskCacheNoCB();
  return net::OK;
}

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

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

MockBlockingBackendFactory::~MockBlockingBackendFactory() {
}

int MockBlockingBackendFactory::CreateBackend(
    net::NetLog* net_log, disk_cache::Backend** backend,
    const net::CompletionCallback& callback) {
  if (!block_) {
    if (!fail_)
      *backend = new MockDiskCache();
    return Result();
  }

  backend_ =  backend;
  callback_ = callback;
  return net::ERR_IO_PENDING;
}

void MockBlockingBackendFactory::FinishCreation() {
  block_ = false;
  if (!callback_.is_null()) {
    if (!fail_)
      *backend_ = new MockDiskCache();
    net::CompletionCallback cb = callback_;
    callback_.Reset();
    cb.Run(Result());  // This object can be deleted here.
  }
}
