// Copyright (c) 2011 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/disk_cache/disk_cache_test_util.h"

#include "base/logging.h"
#include "base/file_util.h"
#include "base/message_loop_proxy.h"
#include "base/path_service.h"
#include "net/base/net_errors.h"
#include "net/disk_cache/backend_impl.h"
#include "net/disk_cache/cache_util.h"
#include "net/disk_cache/file.h"

using base::Time;
using base::TimeDelta;

namespace {

FilePath BuildCachePath(const std::string& name) {
  FilePath path;
  PathService::Get(base::DIR_TEMP, &path);  // Ignore return value;
  path = path.AppendASCII(name);
  if (!file_util::PathExists(path))
    file_util::CreateDirectory(path);

  return path;
}

}  // namespace.

std::string GenerateKey(bool same_length) {
  char key[200];
  CacheTestFillBuffer(key, sizeof(key), same_length);

  key[199] = '\0';
  return std::string(key);
}

void CacheTestFillBuffer(char* buffer, size_t len, bool no_nulls) {
  static bool called = false;
  if (!called) {
    called = true;
    int seed = static_cast<int>(Time::Now().ToInternalValue());
    srand(seed);
  }

  for (size_t i = 0; i < len; i++) {
    buffer[i] = static_cast<char>(rand());
    if (!buffer[i] && no_nulls)
      buffer[i] = 'g';
  }
  if (len && !buffer[0])
    buffer[0] = 'g';
}

FilePath GetCacheFilePath() {
  return BuildCachePath("cache_test");
}

bool CreateCacheTestFile(const FilePath& name) {
  int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
              base::PLATFORM_FILE_READ |
              base::PLATFORM_FILE_WRITE;

  scoped_refptr<disk_cache::File> file(new disk_cache::File(
      base::CreatePlatformFile(name, flags, NULL, NULL)));
  if (!file->IsValid())
    return false;

  file->SetLength(4 * 1024 * 1024);
  return true;
}

bool DeleteCache(const FilePath& path) {
  disk_cache::DeleteCache(path, false);
  return true;
}

bool CopyTestCache(const std::string& name) {
  FilePath path;
  PathService::Get(base::DIR_SOURCE_ROOT, &path);
  path = path.AppendASCII("net");
  path = path.AppendASCII("data");
  path = path.AppendASCII("cache_tests");
  path = path.AppendASCII(name);

  FilePath dest = GetCacheFilePath();
  if (!DeleteCache(dest))
    return false;
  return file_util::CopyDirectory(path, dest, false);
}

bool CheckCacheIntegrity(const FilePath& path, bool new_eviction) {
  scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(
      path, base::MessageLoopProxy::CreateForCurrentThread(), NULL));
  if (!cache.get())
    return false;
  if (new_eviction)
    cache->SetNewEviction();
  cache->SetFlags(disk_cache::kNoRandom);
  if (cache->SyncInit() != net::OK)
    return false;
  return cache->SelfCheck() >= 0;
}

ScopedTestCache::ScopedTestCache() : path_(GetCacheFilePath()) {
  bool result = DeleteCache(path_);
  DCHECK(result);
}

ScopedTestCache::ScopedTestCache(const std::string& name)
    : path_(BuildCachePath(name)) {
  bool result = DeleteCache(path_);
  DCHECK(result);
}

ScopedTestCache::~ScopedTestCache() {
  file_util::Delete(path(), true);
}

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

volatile int g_cache_tests_received = 0;
volatile bool g_cache_tests_error = 0;

CallbackTest::CallbackTest(bool reuse) : result_(-1), reuse_(reuse ? 0 : 1) {}

CallbackTest::~CallbackTest() {}

// On the actual callback, increase the number of tests received and check for
// errors (an unexpected test received)
void CallbackTest::RunWithParams(const Tuple1<int>& params) {
  if (reuse_) {
    DCHECK_EQ(1, reuse_);
    if (2 == reuse_)
      g_cache_tests_error = true;
    reuse_++;
  }

  result_ = params.a;
  g_cache_tests_received++;
}

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

MessageLoopHelper::MessageLoopHelper()
    : num_callbacks_(0),
      num_iterations_(0),
      last_(0),
      completed_(false) {
}

MessageLoopHelper::~MessageLoopHelper() {
}

bool MessageLoopHelper::WaitUntilCacheIoFinished(int num_callbacks) {
  if (num_callbacks == g_cache_tests_received)
    return true;

  ExpectCallbacks(num_callbacks);
  // Create a recurrent timer of 50 mS.
  if (!timer_.IsRunning())
    timer_.Start(TimeDelta::FromMilliseconds(50), this,
                 &MessageLoopHelper::TimerExpired);
  MessageLoop::current()->Run();
  return completed_;
}

// Quits the message loop when all callbacks are called or we've been waiting
// too long for them (2 secs without a callback).
void MessageLoopHelper::TimerExpired() {
  CHECK_LE(g_cache_tests_received, num_callbacks_);
  if (g_cache_tests_received == num_callbacks_) {
    completed_ = true;
    MessageLoop::current()->Quit();
  } else {
    // Not finished yet. See if we have to abort.
    if (last_ == g_cache_tests_received)
      num_iterations_++;
    else
      last_ = g_cache_tests_received;
    if (40 == num_iterations_)
      MessageLoop::current()->Quit();
  }
}
