// Copyright 2016 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 "base/memory/ptr_util.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/browsing_data/cache_test_util.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"

using content::BrowserThread;

CacheTestUtil::CacheTestUtil(content::StoragePartition* partition)
    : partition_(partition), remaining_tasks_(0) {
  done_callback_ =
      base::Bind(&CacheTestUtil::DoneCallback, base::Unretained(this));
  // UI and IO thread synchronization.
  waitable_event_ = base::MakeUnique<base::WaitableEvent>(
      base::WaitableEvent::ResetPolicy::AUTOMATIC,
      base::WaitableEvent::InitialState::NOT_SIGNALED);
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&CacheTestUtil::SetUpOnIOThread, base::Unretained(this)));
  WaitForTasksOnIOThread();
}

CacheTestUtil::~CacheTestUtil() {
  // The cache iterator must be deleted on the thread where it was created,
  // which is the IO thread.
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&CacheTestUtil::TearDownOnIOThread, base::Unretained(this)));
  WaitForTasksOnIOThread();
}

void CacheTestUtil::CreateCacheEntries(const std::set<std::string>& keys) {
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&CacheTestUtil::CreateCacheEntriesOnIOThread,
                 base::Unretained(this), base::ConstRef(keys)));
  WaitForTasksOnIOThread();
}

void CacheTestUtil::SetUpOnIOThread() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  net::URLRequestContextGetter* context = partition_->GetURLRequestContext();

  net::HttpCache* cache =
      context->GetURLRequestContext()->http_transaction_factory()->GetCache();

  SetNumberOfWaitedTasks(1);
  WaitForCompletion(cache->GetBackend(&backend_, done_callback_));
}

void CacheTestUtil::TearDownOnIOThread() {
  iterator_.reset();
  for (disk_cache::Entry* entry : entries_) {
    entry->Close();
  }
  entries_.clear();
  DoneCallback(net::OK);
}

void CacheTestUtil::CreateCacheEntriesOnIOThread(
    const std::set<std::string>& keys) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  int pos = entries_.size();
  entries_.resize(entries_.size() + keys.size());
  SetNumberOfWaitedTasks(keys.size());

  for (const std::string& key : keys) {
    WaitForCompletion(
        backend_->CreateEntry(key, &entries_[pos++], done_callback_));
  }
}

// Waiting for tasks to be done on IO thread. --------------------------------

void CacheTestUtil::WaitForTasksOnIOThread() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  waitable_event_->Wait();
}

void CacheTestUtil::SetNumberOfWaitedTasks(int count) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  remaining_tasks_ = count;
}

void CacheTestUtil::WaitForCompletion(int value) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  if (value >= 0) {
    // We got the result immediately.
    DoneCallback(value);
  } else if (value == net::ERR_IO_PENDING) {
    // We need to wait for the callback.
  } else {
    // An error has occurred.
    NOTREACHED();
  }
}

void CacheTestUtil::DoneCallback(int value) {
  DCHECK_GE(value, 0);  // Negative values represent an error.
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  if (--remaining_tasks_ > 0)
    return;

  waitable_event_->Signal();
}

// Check cache content.
std::vector<std::string> CacheTestUtil::GetEntryKeys() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                          base::Bind(&CacheTestUtil::GetEntryKeysOnIOThread,
                                     base::Unretained(this)));
  WaitForTasksOnIOThread();
  return keys_;
}

void CacheTestUtil::GetEntryKeysOnIOThread() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  keys_.clear();
  current_entry_ = nullptr;
  iterator_ = backend_->CreateIterator();
  GetNextKey(net::OK);
}

void CacheTestUtil::GetNextKey(int error) {
  while (error != net::ERR_IO_PENDING) {
    if (error == net::ERR_FAILED) {
      DoneCallback(net::OK);
      return;
    }

    if (current_entry_) {
      keys_.push_back(current_entry_->GetKey());
    }

    error = iterator_->OpenNextEntry(
        &current_entry_,
        base::Bind(&CacheTestUtil::GetNextKey, base::Unretained(this)));
  }
}
