// Copyright 2014 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 <string>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/pickle.h"
#include "base/run_loop.h"
#include "content/browser/appcache/appcache_response.h"
#include "content/browser/appcache/appcache_service_impl.h"
#include "content/browser/appcache/mock_appcache_storage.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
#include "net/http/http_response_headers.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {
namespace {

const int64 kMockGroupId = 1;
const int64 kMockCacheId = 1;
const int64 kMockResponseId = 1;
const int64 kMissingCacheId = 5;
const int64 kMissingResponseId = 5;
const char kMockHeaders[] =
    "HTTP/1.0 200 OK\0Content-Length: 5\0\0";
const char kMockBody[] = "Hello";
const int kMockBodySize = 5;

class MockResponseReader : public AppCacheResponseReader {
 public:
  MockResponseReader(int64 response_id,
                     net::HttpResponseInfo* info, int info_size,
                     const char* data, int data_size)
      : AppCacheResponseReader(response_id, 0, NULL),
        info_(info), info_size_(info_size),
        data_(data), data_size_(data_size) {
  }
  virtual void ReadInfo(HttpResponseInfoIOBuffer* info_buf,
                        const net::CompletionCallback& callback) OVERRIDE {
    info_buffer_ = info_buf;
    callback_ = callback;  // Cleared on completion.

    int rv = info_.get() ? info_size_ : net::ERR_FAILED;
    info_buffer_->http_info.reset(info_.release());
    info_buffer_->response_data_size = data_size_;
    ScheduleUserCallback(rv);
  }
  virtual void ReadData(net::IOBuffer* buf, int buf_len,
                        const net::CompletionCallback& callback) OVERRIDE {
    buffer_ = buf;
    buffer_len_ = buf_len;
    callback_ = callback;  // Cleared on completion.

    if (!data_) {
      ScheduleUserCallback(net::ERR_CACHE_READ_FAILURE);
      return;
    }
    DCHECK(buf_len >= data_size_);
    memcpy(buf->data(), data_, data_size_);
    ScheduleUserCallback(data_size_);
    data_size_ = 0;
  }

 private:
  void ScheduleUserCallback(int result) {
    base::MessageLoop::current()->PostTask(FROM_HERE,
        base::Bind(&MockResponseReader::InvokeUserCompletionCallback,
                   weak_factory_.GetWeakPtr(), result));
  }

  scoped_ptr<net::HttpResponseInfo> info_;
  int info_size_;
  const char* data_;
  int data_size_;
};

}  // namespace


class AppCacheServiceImplTest : public testing::Test {
 public:
  AppCacheServiceImplTest()
      : kOrigin("http://hello/"),
        kManifestUrl(kOrigin.Resolve("manifest")),
        service_(new AppCacheServiceImpl(NULL)),
        delete_result_(net::OK), delete_completion_count_(0),
        deletion_callback_(
            base::Bind(&AppCacheServiceImplTest::OnDeleteAppCachesComplete,
                       base::Unretained(this))) {
    // Setup to use mock storage.
    service_->storage_.reset(new MockAppCacheStorage(service_.get()));
  }

  void OnDeleteAppCachesComplete(int result) {
    delete_result_ = result;
    ++delete_completion_count_;
  }

  MockAppCacheStorage* mock_storage() {
    return static_cast<MockAppCacheStorage*>(service_->storage());
  }

  void ResetStorage() {
    service_->storage_.reset(new MockAppCacheStorage(service_.get()));
  }

  bool IsGroupStored(const GURL& manifest_url) {
    return mock_storage()->IsGroupForManifestStored(manifest_url);
  }

  int CountPendingHelpers() {
    return service_->pending_helpers_.size();
  }

  void SetupMockGroup() {
    scoped_ptr<net::HttpResponseInfo> info(MakeMockResponseInfo());
    const int kMockInfoSize = GetResponseInfoSize(info.get());

    // Create a mock group, cache, and entry and stuff them into mock storage.
    scoped_refptr<AppCacheGroup> group(
        new AppCacheGroup(service_->storage(), kManifestUrl, kMockGroupId));
    scoped_refptr<AppCache> cache(
        new AppCache(service_->storage(), kMockCacheId));
    cache->AddEntry(
        kManifestUrl,
        AppCacheEntry(AppCacheEntry::MANIFEST, kMockResponseId,
                      kMockInfoSize + kMockBodySize));
    cache->set_complete(true);
    group->AddCache(cache.get());
    mock_storage()->AddStoredGroup(group.get());
    mock_storage()->AddStoredCache(cache.get());
  }

  void SetupMockReader(
      bool valid_info, bool valid_data, bool valid_size) {
    net::HttpResponseInfo* info = valid_info ? MakeMockResponseInfo() : NULL;
    int info_size = info ? GetResponseInfoSize(info) : 0;
    const char* data = valid_data ? kMockBody : NULL;
    int data_size = valid_size ? kMockBodySize : 3;
    mock_storage()->SimulateResponseReader(
        new MockResponseReader(kMockResponseId, info, info_size,
                               data, data_size));
  }

  net::HttpResponseInfo* MakeMockResponseInfo() {
    net::HttpResponseInfo* info = new net::HttpResponseInfo;
    info->request_time = base::Time::Now();
    info->response_time = base::Time::Now();
    info->was_cached = false;
    info->headers = new net::HttpResponseHeaders(
        std::string(kMockHeaders, arraysize(kMockHeaders)));
    return info;
  }

  int GetResponseInfoSize(const net::HttpResponseInfo* info) {
    Pickle pickle;
    return PickleResponseInfo(&pickle, info);
  }

  int PickleResponseInfo(Pickle* pickle, const net::HttpResponseInfo* info) {
    const bool kSkipTransientHeaders = true;
    const bool kTruncated = false;
    info->Persist(pickle, kSkipTransientHeaders, kTruncated);
    return pickle->size();
  }

  const GURL kOrigin;
  const GURL kManifestUrl;

  scoped_ptr<AppCacheServiceImpl> service_;
  int delete_result_;
  int delete_completion_count_;
  net::CompletionCallback deletion_callback_;

 private:
  base::MessageLoop message_loop_;
};

TEST_F(AppCacheServiceImplTest, DeleteAppCachesForOrigin) {
  // Without giving mock storage simiulated info, should fail.
  service_->DeleteAppCachesForOrigin(kOrigin, deletion_callback_);
  EXPECT_EQ(0, delete_completion_count_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, delete_completion_count_);
  EXPECT_EQ(net::ERR_FAILED, delete_result_);
  delete_completion_count_ = 0;

  // Should succeed given an empty info collection.
  mock_storage()->SimulateGetAllInfo(new content::AppCacheInfoCollection);
  service_->DeleteAppCachesForOrigin(kOrigin, deletion_callback_);
  EXPECT_EQ(0, delete_completion_count_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, delete_completion_count_);
  EXPECT_EQ(net::OK, delete_result_);
  delete_completion_count_ = 0;

  scoped_refptr<AppCacheInfoCollection> info(new AppCacheInfoCollection);

  // Should succeed given a non-empty info collection.
  AppCacheInfo mock_manifest_1;
  AppCacheInfo mock_manifest_2;
  AppCacheInfo mock_manifest_3;
  mock_manifest_1.manifest_url = kOrigin.Resolve("manifest1");
  mock_manifest_2.manifest_url = kOrigin.Resolve("manifest2");
  mock_manifest_3.manifest_url = kOrigin.Resolve("manifest3");
  AppCacheInfoVector info_vector;
  info_vector.push_back(mock_manifest_1);
  info_vector.push_back(mock_manifest_2);
  info_vector.push_back(mock_manifest_3);
  info->infos_by_origin[kOrigin] = info_vector;
  mock_storage()->SimulateGetAllInfo(info.get());
  service_->DeleteAppCachesForOrigin(kOrigin, deletion_callback_);
  EXPECT_EQ(0, delete_completion_count_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, delete_completion_count_);
  EXPECT_EQ(net::OK, delete_result_);
  delete_completion_count_ = 0;

  // Should fail if storage fails to delete.
  info->infos_by_origin[kOrigin] = info_vector;
  mock_storage()->SimulateGetAllInfo(info.get());
  mock_storage()->SimulateMakeGroupObsoleteFailure();
  service_->DeleteAppCachesForOrigin(kOrigin, deletion_callback_);
  EXPECT_EQ(0, delete_completion_count_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, delete_completion_count_);
  EXPECT_EQ(net::ERR_FAILED, delete_result_);
  delete_completion_count_ = 0;

  // Should complete with abort error if the service is deleted
  // prior to a delete completion.
  service_->DeleteAppCachesForOrigin(kOrigin, deletion_callback_);
  EXPECT_EQ(0, delete_completion_count_);
  service_.reset();  // kill it
  EXPECT_EQ(1, delete_completion_count_);
  EXPECT_EQ(net::ERR_ABORTED, delete_result_);
  delete_completion_count_ = 0;

  // Let any tasks lingering from the sudden deletion run and verify
  // no other completion calls occur.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, delete_completion_count_);
}

TEST_F(AppCacheServiceImplTest, CheckAppCacheResponse) {
  // Check a non-existing manifest.
  EXPECT_FALSE(IsGroupStored(kManifestUrl));
  service_->CheckAppCacheResponse(kManifestUrl, 1, 1);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, CountPendingHelpers());
  EXPECT_FALSE(IsGroupStored(kManifestUrl));
  ResetStorage();

  // Check a response that looks good.
  // Nothing should be deleted.
  SetupMockGroup();
  EXPECT_TRUE(IsGroupStored(kManifestUrl));
  SetupMockReader(true, true, true);
  service_->CheckAppCacheResponse(kManifestUrl, kMockCacheId, kMockResponseId);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, CountPendingHelpers());
  EXPECT_TRUE(IsGroupStored(kManifestUrl));
  ResetStorage();

  // Check a response for which there is no cache entry.
  // The group should get deleted.
  SetupMockGroup();
  service_->CheckAppCacheResponse(kManifestUrl, kMockCacheId,
                                  kMissingResponseId);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, CountPendingHelpers());
  EXPECT_FALSE(IsGroupStored(kManifestUrl));
  ResetStorage();

  // Check a response for which there is no manifest entry in a newer version
  // of the cache. Nothing should get deleted in this case.
  SetupMockGroup();
  service_->CheckAppCacheResponse(kManifestUrl, kMissingCacheId,
                                  kMissingResponseId);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, CountPendingHelpers());
  EXPECT_TRUE(IsGroupStored(kManifestUrl));
  ResetStorage();

  // Check a response with bad headers.
  SetupMockGroup();
  service_->CheckAppCacheResponse(kManifestUrl, kMockCacheId, kMockResponseId);
  SetupMockReader(false, true, true);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, CountPendingHelpers());
  EXPECT_FALSE(IsGroupStored(kManifestUrl));
  ResetStorage();

  // Check a response with bad data.
  SetupMockGroup();
  service_->CheckAppCacheResponse(kManifestUrl, kMockCacheId, kMockResponseId);
  SetupMockReader(true, false, true);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, CountPendingHelpers());
  EXPECT_FALSE(IsGroupStored(kManifestUrl));
  ResetStorage();

  // Check a response with truncated data.
  SetupMockGroup();
  service_->CheckAppCacheResponse(kManifestUrl, kMockCacheId, kMockResponseId);
  SetupMockReader(true, true, false);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, CountPendingHelpers());
  EXPECT_FALSE(IsGroupStored(kManifestUrl));
  ResetStorage();

  service_.reset();  // Clean up.
  base::RunLoop().RunUntilIdle();
}

// Just tests the backoff scheduling function, not the actual reinit function.
TEST_F(AppCacheServiceImplTest, ScheduleReinitialize) {
  const base::TimeDelta kNoDelay;
  const base::TimeDelta kOneSecond(base::TimeDelta::FromSeconds(1));
  const base::TimeDelta k30Seconds(base::TimeDelta::FromSeconds(30));
  const base::TimeDelta kOneHour(base::TimeDelta::FromHours(1));

  // Do things get initialized as expected?
  scoped_ptr<AppCacheServiceImpl> service(new AppCacheServiceImpl(NULL));
  EXPECT_TRUE(service->last_reinit_time_.is_null());
  EXPECT_FALSE(service->reinit_timer_.IsRunning());
  EXPECT_EQ(kNoDelay, service->next_reinit_delay_);

  // Do we see artifacts of the timer pending and such?
  service->ScheduleReinitialize();
  EXPECT_TRUE(service->reinit_timer_.IsRunning());
  EXPECT_EQ(kNoDelay, service->reinit_timer_.GetCurrentDelay());
  EXPECT_EQ(k30Seconds, service->next_reinit_delay_);

  // Nothing should change if already scheduled
  service->ScheduleReinitialize();
  EXPECT_TRUE(service->reinit_timer_.IsRunning());
  EXPECT_EQ(kNoDelay, service->reinit_timer_.GetCurrentDelay());
  EXPECT_EQ(k30Seconds, service->next_reinit_delay_);

  // Does the delay increase as expected?
  service->reinit_timer_.Stop();
  service->last_reinit_time_ = base::Time::Now() - kOneSecond;
  service->ScheduleReinitialize();
  EXPECT_TRUE(service->reinit_timer_.IsRunning());
  EXPECT_EQ(k30Seconds, service->reinit_timer_.GetCurrentDelay());
  EXPECT_EQ(k30Seconds + k30Seconds, service->next_reinit_delay_);

  // Does the delay reset as expected?
  service->reinit_timer_.Stop();
  service->last_reinit_time_ = base::Time::Now() -
                               base::TimeDelta::FromHours(2);
  service->ScheduleReinitialize();
  EXPECT_TRUE(service->reinit_timer_.IsRunning());
  EXPECT_EQ(kNoDelay, service->reinit_timer_.GetCurrentDelay());
  EXPECT_EQ(k30Seconds, service->next_reinit_delay_);

  // Does the delay max out as expected?
  service->reinit_timer_.Stop();
  service->last_reinit_time_ = base::Time::Now() - kOneSecond;
  service->next_reinit_delay_ = kOneHour;
  service->ScheduleReinitialize();
  EXPECT_TRUE(service->reinit_timer_.IsRunning());
  EXPECT_EQ(kOneHour, service->reinit_timer_.GetCurrentDelay());
  EXPECT_EQ(kOneHour, service->next_reinit_delay_);

  // Fine to delete while pending.
  service.reset(NULL);
}



}  // namespace content
