// 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 "base/location.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/prefs/testing_pref_store.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/test/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
#include "net/base/sdch_manager.h"
#include "net/log/net_log.h"
#include "net/sdch/sdch_owner.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

bool GetDictionaryForURL(TestingPrefStore* store,
                         const GURL& url,
                         std::string* hash,
                         base::DictionaryValue** dict) {
  base::Value* sdch_val = nullptr;
  base::DictionaryValue* sdch_dict = nullptr;
  if (!store->GetMutableValue("SDCH", &sdch_val))
    return false;
  if (!sdch_val->GetAsDictionary(&sdch_dict))
    return false;

  base::DictionaryValue* dicts_dict = nullptr;
  if (!sdch_dict->GetDictionary("dictionaries", &dicts_dict))
    return false;

  base::DictionaryValue::Iterator it(*dicts_dict);
  while (!it.IsAtEnd()) {
    const base::DictionaryValue* d = nullptr;
    if (!it.value().GetAsDictionary(&d))
      continue;
    std::string dict_url;
    if (d->GetString("url", &dict_url) && dict_url == url.spec()) {
      if (hash)
        *hash = it.key();
      if (dict)
        dicts_dict->GetDictionary(it.key(), dict);
      return true;
    }
    it.Advance();
  }

  return false;
}

}  // namespace

namespace net {

static const char generic_url[] = "http://www.example.com";
static const char generic_domain[] = "www.example.com";

static std::string NewSdchDictionary(size_t dictionary_size) {
  std::string dictionary;
  dictionary.append("Domain: ");
  dictionary.append(generic_domain);
  dictionary.append("\n");
  dictionary.append("\n");

  size_t original_dictionary_size = dictionary.size();
  dictionary.resize(dictionary_size);
  for (size_t i = original_dictionary_size; i < dictionary_size; ++i)
    dictionary[i] = static_cast<char>((i % 127) + 1);

  return dictionary;
}

int outstanding_url_request_error_counting_jobs = 0;
base::Closure* empty_url_request_jobs_callback = 0;

// Variation of URLRequestErrorJob to count number of outstanding
// instances and notify when that goes to zero.
class URLRequestErrorCountingJob : public URLRequestJob {
 public:
  URLRequestErrorCountingJob(URLRequest* request,
                             NetworkDelegate* network_delegate,
                             int error)
      : URLRequestJob(request, network_delegate),
        error_(error),
        weak_factory_(this) {
    ++outstanding_url_request_error_counting_jobs;
  }

  void Start() override {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::Bind(&URLRequestErrorCountingJob::StartAsync,
                              weak_factory_.GetWeakPtr()));
  }

 private:
  ~URLRequestErrorCountingJob() override {
    --outstanding_url_request_error_counting_jobs;
    if (0 == outstanding_url_request_error_counting_jobs &&
        empty_url_request_jobs_callback) {
      empty_url_request_jobs_callback->Run();
    }
  }

  void StartAsync() {
    NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, error_));
  }

  int error_;

  base::WeakPtrFactory<URLRequestErrorCountingJob> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(URLRequestErrorCountingJob);
};

static int error_jobs_created = 0;

class MockURLRequestJobFactory : public URLRequestJobFactory {
 public:
  MockURLRequestJobFactory() {}

  ~MockURLRequestJobFactory() override {}

  URLRequestJob* MaybeCreateJobWithProtocolHandler(
      const std::string& scheme,
      URLRequest* request,
      NetworkDelegate* network_delegate) const override {
    ++error_jobs_created;
    return new URLRequestErrorCountingJob(request, network_delegate,
                                          ERR_INTERNET_DISCONNECTED);
  }

  URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
                                        NetworkDelegate* network_delegate,
                                        const GURL& location) const override {
    return nullptr;
  }

  URLRequestJob* MaybeInterceptResponse(
      URLRequest* request,
      NetworkDelegate* network_delegate) const override {
    return nullptr;
  }

  bool IsHandledProtocol(const std::string& scheme) const override {
    return scheme == "http";
  };

  bool IsHandledURL(const GURL& url) const override {
    return url.SchemeIs("http");
  }

  bool IsSafeRedirectTarget(const GURL& location) const override {
    return false;
  }
};

class MockSdchDictionaryFetcher : public SdchDictionaryFetcher {
 public:
  MockSdchDictionaryFetcher() : SdchDictionaryFetcher(&test_context_) {}
  ~MockSdchDictionaryFetcher() {}

  struct PendingRequest {
    PendingRequest(const GURL& url,
                   const OnDictionaryFetchedCallback& callback)
        : url_(url), callback_(callback) {}
    GURL url_;
    OnDictionaryFetchedCallback callback_;
  };

  virtual bool Schedule(const GURL& dictionary_url,
                        const OnDictionaryFetchedCallback& callback) {
    if (!HasPendingRequest(dictionary_url)) {
      requests_.push_back(PendingRequest(dictionary_url, callback));
      return true;
    }
    return false;
  }

  virtual bool ScheduleReload(const GURL& dictionary_url,
                              const OnDictionaryFetchedCallback& callback) {
    if (!HasPendingRequest(dictionary_url)) {
      requests_.push_back(PendingRequest(dictionary_url, callback));
      return true;
    }
    return false;
  }

  virtual void Cancel() {
    requests_.clear();
  }

  bool HasPendingRequest(const GURL& dictionary_url) {
    for (std::vector<PendingRequest>::iterator it = requests_.begin();
         it != requests_.end(); ++it) {
      if (it->url_ == dictionary_url)
        return true;
    }
    return false;
  }

  bool CompletePendingRequest(const GURL& dictionary_url,
                              const std::string& dictionary_text,
                              const BoundNetLog& net_log,
                              bool was_from_cache) {
    for (std::vector<PendingRequest>::iterator it = requests_.begin();
         it != requests_.end(); ++it) {
      if (it->url_ == dictionary_url) {
        it->callback_.Run(dictionary_text, dictionary_url, net_log,
                          was_from_cache);
        requests_.erase(it);
        return true;
      }
    }
    return false;
  }

 private:
  TestURLRequestContext test_context_;
  std::vector<PendingRequest> requests_;
  DISALLOW_COPY_AND_ASSIGN(MockSdchDictionaryFetcher);
};

// File testing infrastructure summary:
// * NewSdchDictionary(): Creates a dictionary of a specific size.
// * URLRequestErrorCountingJob: A URLRequestJob that returns an error
//   and counts the number of outstanding (started but not finished)
//   jobs, and calls a global callback when that number transitions to zero.
// * MockURLRequestJobFactory: Factory to create the above jobs.  Tracks
//   the number of jobs created.
// * SdchOwnerTest: Interfaces
//      * Access manager, owner, and net log
//      * Return the number of jobs created in a time interval
//      * Return dictionary present in the manager
//      * Notify SdchOwner of an incoming dictionary (& wait until jobs clear)
//      * Attempt to add a dictionary and test for success.
// Test patterns:
//      * Let the owner know about a Get-Dictionary header and test for
//        appropriate jobs being created.
//      * Let the owner know that a dictionary was successfully fetched
//        and test for appropriate outcome.
//      * Either of the above, having previously added dictionaries to create
//        a particular initial state.
class SdchOwnerTest : public testing::Test {
 public:
  static const size_t kMaxSizeForTesting = 1000 * 50;
  static const size_t kMinFetchSpaceForTesting = 500;

  SdchOwnerTest()
      : last_jobs_created_(error_jobs_created),
        dictionary_creation_index_(0),
        pref_store_(new TestingPrefStore),
        sdch_owner_(new SdchOwner(&sdch_manager_, &url_request_context_)) {
    // Any jobs created on this context will immediately error,
    // which leaves the test in control of signals to SdchOwner.
    url_request_context_.set_job_factory(&job_factory_);

    // Reduce sizes to reduce time for string operations.
    sdch_owner_->SetMaxTotalDictionarySize(kMaxSizeForTesting);
    sdch_owner_->SetMinSpaceForDictionaryFetch(kMinFetchSpaceForTesting);
  }

  SdchManager& sdch_manager() { return sdch_manager_; }
  SdchOwner& sdch_owner() { return *(sdch_owner_.get()); }
  BoundNetLog& bound_net_log() { return net_log_; }
  TestingPrefStore& pref_store() { return *(pref_store_.get()); }

  int JobsRecentlyCreated() {
    int result = error_jobs_created - last_jobs_created_;
    last_jobs_created_ = error_jobs_created;
    return result;
  }

  bool DictionaryPresentInManager(const std::string& server_hash) {
    // Presumes all tests use generic url.
    SdchProblemCode tmp;
    scoped_ptr<SdchManager::DictionarySet> set(
        sdch_manager_.GetDictionarySetByHash(GURL(generic_url), server_hash,
                                             &tmp));
    return !!set.get();
  }

  void WaitForNoJobs() {
    if (outstanding_url_request_error_counting_jobs == 0)
      return;

    base::RunLoop run_loop;
    base::Closure quit_closure(run_loop.QuitClosure());
    empty_url_request_jobs_callback = &quit_closure;
    run_loop.Run();
    empty_url_request_jobs_callback = NULL;
  }

  void SignalGetDictionaryAndClearJobs(GURL request_url, GURL dictionary_url) {
    sdch_owner().OnGetDictionary(request_url, dictionary_url);
    WaitForNoJobs();
  }

  // Create a unique (by hash) dictionary of the given size,
  // associate it with a unique URL, add it to the manager through
  // SdchOwner::OnDictionaryFetched(), and return whether that
  // addition was successful or not.
  bool CreateAndAddDictionary(size_t size,
                              std::string* server_hash_p,
                              base::Time last_used_time) {
    GURL dictionary_url(
        base::StringPrintf("%s/d%d", generic_url, dictionary_creation_index_));
    std::string dictionary_text(NewSdchDictionary(size - 4));
    dictionary_text += base::StringPrintf("%04d", dictionary_creation_index_);
    ++dictionary_creation_index_;
    std::string client_hash;
    std::string server_hash;
    SdchManager::GenerateHash(dictionary_text, &client_hash, &server_hash);

    if (DictionaryPresentInManager(server_hash))
      return false;
    sdch_owner().OnDictionaryFetched(last_used_time, 0, dictionary_text,
                                     dictionary_url, net_log_, false);
    if (server_hash_p)
      *server_hash_p = server_hash;
    return DictionaryPresentInManager(server_hash);
  }

  void ResetOwner() {
    sdch_owner_.reset(new SdchOwner(&sdch_manager_, &url_request_context_));
  }

 private:
  int last_jobs_created_;
  BoundNetLog net_log_;
  int dictionary_creation_index_;

  // The dependencies of these objects (sdch_owner_ -> {sdch_manager_,
  // url_request_context_}, url_request_context_->job_factory_) require
  // this order for correct destruction semantics.
  MockURLRequestJobFactory job_factory_;
  URLRequestContext url_request_context_;
  SdchManager sdch_manager_;
  scoped_refptr<TestingPrefStore> pref_store_;
  scoped_ptr<SdchOwner> sdch_owner_;

  DISALLOW_COPY_AND_ASSIGN(SdchOwnerTest);
};

// Does OnGetDictionary result in a fetch when there's enough space, and not
// when there's not?
TEST_F(SdchOwnerTest, OnGetDictionary_Fetching) {
  GURL request_url(std::string(generic_url) + "/r1");

  // Fetch generated when empty.
  GURL dict_url1(std::string(generic_url) + "/d1");
  EXPECT_EQ(0, JobsRecentlyCreated());
  SignalGetDictionaryAndClearJobs(request_url, dict_url1);
  EXPECT_EQ(1, JobsRecentlyCreated());

  // Fetch generated when half full.
  GURL dict_url2(std::string(generic_url) + "/d2");
  std::string dictionary1(NewSdchDictionary(kMaxSizeForTesting / 2));
  sdch_owner().OnDictionaryFetched(base::Time::Now(), 1, dictionary1,
                                   dict_url1, bound_net_log(), false);
  EXPECT_EQ(0, JobsRecentlyCreated());
  SignalGetDictionaryAndClearJobs(request_url, dict_url2);
  EXPECT_EQ(1, JobsRecentlyCreated());

  // Fetch not generated when close to completely full.
  GURL dict_url3(std::string(generic_url) + "/d3");
  std::string dictionary2(NewSdchDictionary(
      (kMaxSizeForTesting / 2 - kMinFetchSpaceForTesting / 2)));
  sdch_owner().OnDictionaryFetched(base::Time::Now(), 1, dictionary2,
                                   dict_url2, bound_net_log(), false);
  EXPECT_EQ(0, JobsRecentlyCreated());
  SignalGetDictionaryAndClearJobs(request_url, dict_url3);
  EXPECT_EQ(0, JobsRecentlyCreated());
}

// Make sure attempts to add dictionaries do what they should.
TEST_F(SdchOwnerTest, OnDictionaryFetched_Fetching) {
  GURL request_url(std::string(generic_url) + "/r1");
  std::string client_hash;
  std::string server_hash;

  // In the past, but still fresh for an unused dictionary.
  base::Time dictionary_last_used_time(base::Time::Now() -
                                       base::TimeDelta::FromMinutes(30));

  // Add successful when empty.
  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, nullptr,
                                     dictionary_last_used_time));
  EXPECT_EQ(0, JobsRecentlyCreated());

  // Add successful when half full.
  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, nullptr,
                                     dictionary_last_used_time));
  EXPECT_EQ(0, JobsRecentlyCreated());

  // Add unsuccessful when full.
  EXPECT_FALSE(CreateAndAddDictionary(kMaxSizeForTesting / 2, nullptr,
                                      dictionary_last_used_time));
  EXPECT_EQ(0, JobsRecentlyCreated());
}

// Confirm auto-eviction happens if space is needed.
TEST_F(SdchOwnerTest, ConfirmAutoEviction) {
  base::Time start_time = base::Time::Now();
  std::string server_hash_d1;
  std::string server_hash_d2;
  std::string server_hash_d3;

  base::SimpleTestClock* test_clock = new base::SimpleTestClock();
  sdch_owner().SetClockForTesting(make_scoped_ptr(test_clock));
  test_clock->SetNow(base::Time::Now());

  // Add two dictionaries, one recent, one more than a day in the past.
  base::Time fresh(base::Time::Now() - base::TimeDelta::FromHours(23));
  base::Time stale(base::Time::Now() - base::TimeDelta::FromHours(25));

  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d1, fresh));
  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d2, stale));

  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));

  base::HistogramTester tester;
  const base::TimeDelta synthetic_delta = base::TimeDelta::FromSeconds(5);

  test_clock->Advance(synthetic_delta);

  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d3, fresh));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));

  base::TimeDelta expected_proc_lifetime = synthetic_delta * 3 +
    base::Time::Now() -  start_time;
  size_t expected_value_base = ((kMaxSizeForTesting / 2) *
                                synthetic_delta.InMilliseconds()) /
                                expected_proc_lifetime.InMilliseconds();

  const char *kHistogram = "Sdch3.TimeWeightedMemoryUse";
  tester.ExpectTotalCount(kHistogram, 0);

  // Dictionary insertions and deletions:
  // T = 0: insert d1 and d2
  // T = 5: insert d3, which evicts d2
  // T = 15: destroy SdchOwner, which evicts d1 and d3
  // Therefore, d2's lifetime is synthetic_delta, d1's is synthetic_delta * 3,
  // and d3's is synthetic_delta * 2. The expected_value_base variable is the
  // base factor for d2's memory consumption, of which d1's and d3's are
  // multiples.
  test_clock->Advance(synthetic_delta * 2);
  ResetOwner();

  tester.ExpectTotalCount(kHistogram, 3);
  tester.ExpectBucketCount(kHistogram, expected_value_base, 1);
  tester.ExpectBucketCount(kHistogram, expected_value_base * 2, 1);
  tester.ExpectBucketCount(kHistogram, expected_value_base * 3, 1);
}

// Confirm auto-eviction happens if space is needed, with a more complicated
// situation
TEST_F(SdchOwnerTest, ConfirmAutoEviction_2) {
  std::string server_hash_d1;
  std::string server_hash_d2;
  std::string server_hash_d3;

  // Add dictionaries, one recent, two more than a day in the past that
  // between them add up to the space needed.
  base::Time fresh(base::Time::Now() - base::TimeDelta::FromHours(23));
  base::Time stale(base::Time::Now() - base::TimeDelta::FromHours(25));
  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d1, fresh));

  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d2, stale));
  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d3, stale));

  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));

  std::string server_hash_d4;
  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d4, fresh));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d3));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d4));
}

// Confirm if only one dictionary needs to be evicted it's the oldest.
TEST_F(SdchOwnerTest, ConfirmAutoEviction_Oldest) {
  std::string server_hash_d1;
  std::string server_hash_d2;
  std::string server_hash_d3;

  // Add dictionaries, one recent, one two days in the past, and one
  // four days in the past.
  base::Time fresh(base::Time::Now() - base::TimeDelta::FromHours(23));
  base::Time stale_newer(base::Time::Now() - base::TimeDelta::FromHours(47));
  base::Time stale_older(base::Time::Now() - base::TimeDelta::FromHours(71));

  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d1, fresh));

  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d2,
                                     stale_newer));

  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d3,
                                     stale_older));

  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));

  // The addition of a new dictionary should succeed, evicting only the
  // oldest one.

  std::string server_hash_d4;
  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d4, fresh));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d3));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d4));
}

// Confirm using a dictionary changes eviction behavior properly.
TEST_F(SdchOwnerTest, UseChangesEviction) {
  std::string server_hash_d1;
  std::string server_hash_d2;
  std::string server_hash_d3;

  // Add dictionaries, one recent, one two days in the past, and one
  // four days in the past.
  base::Time fresh(base::Time::Now() - base::TimeDelta::FromHours(23));
  base::Time stale_newer(base::Time::Now() - base::TimeDelta::FromHours(47));
  base::Time stale_older(base::Time::Now() - base::TimeDelta::FromHours(71));

  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d1, fresh));

  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d2,
                                     stale_newer));

  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d3,
                                     stale_older));

  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));

  // Use the oldest dictionary.
  sdch_owner().OnDictionaryUsed(server_hash_d3);

  // The addition of a new dictionary should succeed, evicting only the
  // newer stale one.
  std::string server_hash_d4;
  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d4, fresh));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d4));
}

// Confirm using a dictionary can prevent the addition of a new dictionary.
TEST_F(SdchOwnerTest, UsePreventsAddition) {
  std::string server_hash_d1;
  std::string server_hash_d2;
  std::string server_hash_d3;

  // Add dictionaries, one recent, one two days in the past, and one
  // four days in the past.
  base::Time fresh(base::Time::Now() - base::TimeDelta::FromMinutes(30));
  base::Time stale_newer(base::Time::Now() - base::TimeDelta::FromHours(47));
  base::Time stale_older(base::Time::Now() - base::TimeDelta::FromHours(71));

  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d1, fresh));

  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d2,
                                     stale_newer));

  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 4, &server_hash_d3,
                                     stale_older));

  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));

  // Use the older dictionaries.
  sdch_owner().OnDictionaryUsed(server_hash_d2);
  sdch_owner().OnDictionaryUsed(server_hash_d3);

  // The addition of a new dictionary should fail, not evicting anything.
  std::string server_hash_d4;
  EXPECT_FALSE(
      CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d4, fresh));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d2));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d3));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d4));
}

// Confirm clear gets all the space back.
TEST_F(SdchOwnerTest, ClearReturnsSpace) {
  std::string server_hash_d1;
  std::string server_hash_d2;

  // Take up all the space.
  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting, &server_hash_d1,
                                     base::Time::Now()));
  // Addition should fail.
  EXPECT_FALSE(CreateAndAddDictionary(kMaxSizeForTesting, &server_hash_d2,
                                      base::Time::Now()));
  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));
  sdch_manager().ClearData();
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));

  // Addition should now succeed.
  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting, nullptr, base::Time::Now()));
}

// Confirm memory pressure gets all the space back.
TEST_F(SdchOwnerTest, MemoryPressureReturnsSpace) {
  std::string server_hash_d1;
  std::string server_hash_d2;

  // Take up all the space.
  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting, &server_hash_d1,
                                     base::Time::Now()));

  // Addition should fail.
  EXPECT_FALSE(CreateAndAddDictionary(kMaxSizeForTesting, &server_hash_d2,
                                      base::Time::Now()));

  EXPECT_TRUE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));

  base::MemoryPressureListener::NotifyMemoryPressure(
      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
  // The notification may have (implementation note: does :-}) use a PostTask,
  // so we drain the local message queue.  This should be safe (i.e. not have
  // an inifinite number of messages) in a unit test.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d1));
  EXPECT_FALSE(DictionaryPresentInManager(server_hash_d2));

  // Addition should now succeed.
  EXPECT_TRUE(
      CreateAndAddDictionary(kMaxSizeForTesting, nullptr, base::Time::Now()));
}

// Confirm that use of a pinned dictionary after its removal works properly.
TEST_F(SdchOwnerTest, PinRemoveUse) {
  pref_store().SetInitializationCompleted();
  sdch_owner().EnablePersistentStorage(&pref_store());

  std::string server_hash_d1;
  EXPECT_TRUE(CreateAndAddDictionary(kMaxSizeForTesting / 2, &server_hash_d1,
                                     base::Time::Now()));

  scoped_ptr<SdchManager::DictionarySet> return_set(
      sdch_manager().GetDictionarySet(
          GURL(std::string(generic_url) + "/x.html")));
  ASSERT_TRUE(return_set.get());
  EXPECT_TRUE(return_set->GetDictionaryText(server_hash_d1));

  const base::Value* result = nullptr;
  const base::DictionaryValue* dict_result = nullptr;
  ASSERT_TRUE(pref_store().GetValue("SDCH", &result));
  ASSERT_TRUE(result->GetAsDictionary(&dict_result));
  EXPECT_TRUE(dict_result->Get("dictionaries", &result));
  EXPECT_TRUE(dict_result->Get("dictionaries." + server_hash_d1, &result));

  sdch_manager().ClearData();

  ASSERT_TRUE(pref_store().GetValue("SDCH", &result));
  ASSERT_TRUE(result->GetAsDictionary(&dict_result));
  EXPECT_TRUE(dict_result->Get("dictionaries", &result));
  EXPECT_FALSE(dict_result->Get("dictionaries." + server_hash_d1, &result));

  scoped_ptr<SdchManager::DictionarySet> return_set2(
      sdch_manager().GetDictionarySet(
          GURL(std::string(generic_url) + "/x.html")));
  EXPECT_FALSE(return_set2.get());

  sdch_manager().OnDictionaryUsed(server_hash_d1);

  ASSERT_TRUE(pref_store().GetValue("SDCH", &result));
  ASSERT_TRUE(result->GetAsDictionary(&dict_result));
  EXPECT_TRUE(dict_result->Get("dictionaries", &result));
  EXPECT_FALSE(dict_result->Get("dictionaries." + server_hash_d1, &result));
}

class SdchOwnerPersistenceTest : public ::testing::Test {
 public:
  SdchOwnerPersistenceTest() : pref_store_(new TestingPrefStore()) {
    pref_store_->SetInitializationCompleted();
  }
  virtual ~SdchOwnerPersistenceTest() {}

  void ClearOwner() {
    owner_.reset(NULL);
  }

  void ResetOwner(bool delay) {
    // This has to be done first, since SdchOwner may be observing SdchManager,
    // and SdchManager can't be destroyed with a live observer.
    owner_.reset(NULL);
    manager_.reset(new SdchManager());
    fetcher_ = new MockSdchDictionaryFetcher();
    owner_.reset(new SdchOwner(manager_.get(),
                               &url_request_context_));
    owner_->SetMaxTotalDictionarySize(SdchOwnerTest::kMaxSizeForTesting);
    owner_->SetMinSpaceForDictionaryFetch(
        SdchOwnerTest::kMinFetchSpaceForTesting);
    owner_->SetFetcherForTesting(make_scoped_ptr(fetcher_));
    if (!delay)
      owner_->EnablePersistentStorage(pref_store_.get());
  }

  void InsertDictionaryForURL(const GURL& url, const std::string& nonce) {
    owner_->OnDictionaryFetched(base::Time::Now(), 1,
                                CreateDictionary(url, nonce),
                                url, net_log_, false);
  }

  bool CompleteLoadFromURL(const GURL& url, const std::string& nonce,
                           bool was_from_cache) {
    return fetcher_->CompletePendingRequest(url, CreateDictionary(url, nonce),
                                            net_log_, was_from_cache);
  }

  std::string CreateDictionary(const GURL& url, const std::string& nonce) {
    std::string dict;
    dict.append("Domain: ");
    dict.append(url.host());
    dict.append("\n\n");
    dict.append(url.spec());
    dict.append(nonce);
    return dict;
  }

 protected:
  BoundNetLog net_log_;
  scoped_refptr<TestingPrefStore> pref_store_;
  scoped_ptr<SdchManager> manager_;
  MockSdchDictionaryFetcher* fetcher_;
  scoped_ptr<SdchOwner> owner_;
  TestURLRequestContext url_request_context_;
};

// Test an empty persistence store.
TEST_F(SdchOwnerPersistenceTest, Empty) {
  ResetOwner(false);
  EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
}

// Test a persistence store with an empty dictionary.
TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDict) {
  pref_store_->SetValue("SDCH", make_scoped_ptr(new base::DictionaryValue()),
                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
  ResetOwner(false);
  EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
}

// Test a persistence store with a bad version number.
TEST_F(SdchOwnerPersistenceTest, Persistent_BadVersion) {
  scoped_ptr<base::DictionaryValue> sdch_dict(new base::DictionaryValue());
  sdch_dict->SetInteger("version", 2);
  pref_store_->SetValue("SDCH", sdch_dict.Pass(),
                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);

  ResetOwner(false);
  EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
}

// Test a persistence store with an empty dictionaries map.
TEST_F(SdchOwnerPersistenceTest, Persistent_EmptyDictList) {
  scoped_ptr<base::DictionaryValue> sdch_dict(new base::DictionaryValue());
  scoped_ptr<base::DictionaryValue> dicts(new base::DictionaryValue());
  sdch_dict->SetInteger("version", 1);
  sdch_dict->Set("dictionaries", dicts.Pass());
  pref_store_->SetValue("SDCH", sdch_dict.Pass(),
                        WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);

  ResetOwner(false);
  EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
}

TEST_F(SdchOwnerPersistenceTest, OneDict) {
  const GURL url("http://www.example.com/dict");
  ResetOwner(false);
  EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
  InsertDictionaryForURL(url, "0");
  EXPECT_EQ(1, owner_->GetDictionaryCountForTesting());

  ResetOwner(false);
  EXPECT_EQ(0, owner_->GetDictionaryCountForTesting());
  EXPECT_TRUE(CompleteLoadFromURL(url, "0", true));
  EXPECT_EQ(1, owner_->GetDictionaryCountForTesting());
}

TEST_F(SdchOwnerPersistenceTest, TwoDicts) {
  const GURL url0("http://www.example.com/dict0");
  const GURL url1("http://www.example.com/dict1");
  ResetOwner(false);
  InsertDictionaryForURL(url0, "0");
  InsertDictionaryForURL(url1, "1");

  ResetOwner(false);
  EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true));
  EXPECT_TRUE(CompleteLoadFromURL(url1, "1", true));
  EXPECT_EQ(2, owner_->GetDictionaryCountForTesting());
  EXPECT_TRUE(owner_->HasDictionaryFromURLForTesting(url0));
  EXPECT_TRUE(owner_->HasDictionaryFromURLForTesting(url1));
}

TEST_F(SdchOwnerPersistenceTest, OneGoodDictOneBadDict) {
  const GURL url0("http://www.example.com/dict0");
  const GURL url1("http://www.example.com/dict1");
  ResetOwner(false);
  InsertDictionaryForURL(url0, "0");
  InsertDictionaryForURL(url1, "1");

  // Mutate the pref store a bit now. Clear the owner first, to ensure that the
  // SdchOwner doesn't observe these changes and object. The manual dictionary
  // manipulation is a bit icky.
  ClearOwner();
  base::DictionaryValue* dict = nullptr;
  ASSERT_TRUE(GetDictionaryForURL(pref_store_.get(), url1, nullptr, &dict));
  dict->Remove("use_count", nullptr);

  ResetOwner(false);
  EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true));
  EXPECT_FALSE(CompleteLoadFromURL(url1, "1", true));
  EXPECT_EQ(1, owner_->GetDictionaryCountForTesting());
  EXPECT_TRUE(owner_->HasDictionaryFromURLForTesting(url0));
  EXPECT_FALSE(owner_->HasDictionaryFromURLForTesting(url1));
}

TEST_F(SdchOwnerPersistenceTest, UsingDictionaryUpdatesUseCount) {
  const GURL url("http://www.example.com/dict");
  ResetOwner(false);
  InsertDictionaryForURL(url, "0");

  std::string hash;
  int old_count;
  {
    ClearOwner();
    base::DictionaryValue* dict = nullptr;
    ASSERT_TRUE(GetDictionaryForURL(pref_store_.get(), url, &hash, &dict));
    ASSERT_TRUE(dict->GetInteger("use_count", &old_count));
  }

  ResetOwner(false);
  ASSERT_TRUE(CompleteLoadFromURL(url, "0", true));
  owner_->OnDictionaryUsed(hash);

  int new_count;
  {
    ClearOwner();
    base::DictionaryValue* dict = nullptr;
    ASSERT_TRUE(GetDictionaryForURL(pref_store_.get(), url, nullptr, &dict));
    ASSERT_TRUE(dict->GetInteger("use_count", &new_count));
  }

  EXPECT_EQ(old_count + 1, new_count);
}

TEST_F(SdchOwnerPersistenceTest, LoadingDictionaryMerges) {
  const GURL url0("http://www.example.com/dict0");
  const GURL url1("http://www.example.com/dict1");

  ResetOwner(false);
  InsertDictionaryForURL(url1, "1");

  ResetOwner(true);
  InsertDictionaryForURL(url0, "0");
  EXPECT_EQ(1, owner_->GetDictionaryCountForTesting());
  owner_->EnablePersistentStorage(pref_store_.get());
  ASSERT_TRUE(CompleteLoadFromURL(url1, "1", true));
  EXPECT_EQ(2, owner_->GetDictionaryCountForTesting());
}

TEST_F(SdchOwnerPersistenceTest, PersistenceMetrics) {
  const GURL url0("http://www.example.com/dict0");
  const GURL url1("http://www.example.com/dict1");
  ResetOwner(false);

  InsertDictionaryForURL(url0, "0");
  InsertDictionaryForURL(url1, "1");

  ResetOwner(false);

  base::HistogramTester tester;

  EXPECT_TRUE(CompleteLoadFromURL(url0, "0", true));
  EXPECT_TRUE(CompleteLoadFromURL(url1, "1", false));

  tester.ExpectTotalCount("Sdch3.NetworkBytesSpent", 1);
  tester.ExpectUniqueSample("Sdch3.NetworkBytesSpent",
                            CreateDictionary(url1, "1").size(), 1);
}

}  // namespace net
