/*
 * Copyright 2013 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Author: pulkitg@google.com (Pulkit Goyal)

// Unit test for CachePropertyStore.

#include "pagespeed/opt/http/cache_property_store.h"

#include <cstddef>

#include "pagespeed/kernel/base/cache_interface.h"
#include "pagespeed/kernel/base/callback.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/mock_timer.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/shared_string.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/cache/lru_cache.h"
#include "pagespeed/kernel/util/platform.h"
#include "pagespeed/kernel/util/simple_stats.h"
#include "pagespeed/opt/http/abstract_property_store_get_callback.h"
#include "pagespeed/opt/http/mock_property_page.h"
#include "pagespeed/opt/http/property_cache.pb.h"

namespace net_instaweb {

namespace {

const size_t kMaxCacheSize = 200;
const char kCohortName1[] = "cohort1";
const char kCohortName2[] = "cohort2";
const char kUrl[] = "www.test.com/sample.html";
const char kParsableContent[] =
    "value { name: 'prop1' value: 'value1' }";
const char kNonParsableContent[] = "random";
const char kOptionsSignatureHash[] = "hash";
const char kCacheKeySuffix[] = "CacheKeySuffix";

}  // namespace

class CachePropertyStoreTest : public testing::Test {
 public:
  CachePropertyStoreTest()
     : lru_cache_(kMaxCacheSize),
       thread_system_(Platform::CreateThreadSystem()),
       stats_(thread_system_.get()),
       timer_(thread_system_->NewMutex(), MockTimer::kApr_5_2010_ms),
       cache_property_store_(
           "test/", &lru_cache_, &timer_, &stats_, thread_system_.get()),
       property_cache_(&cache_property_store_,
                       &timer_,
                       &stats_,
                       thread_system_.get()),
       num_callback_with_false_called_(0),
       num_callback_with_true_called_(0),
       cache_lookup_status_(false) {
    PropertyCache::InitCohortStats(kCohortName1, &stats_);
    PropertyStoreGetCallback::InitStats(&stats_);
    cohort_ = property_cache_.AddCohort(kCohortName1);
    cache_property_store_.AddCohort(kCohortName1);
    cohort_list_.push_back(cohort_);
  }

  void SetUp() {
    page_.reset(
        new MockPropertyPage(
            thread_system_.get(),
            &property_cache_,
            kUrl,
            kOptionsSignatureHash,
            kCacheKeySuffix));
    property_cache_.Read(page_.get());
  }

  void ResultCallback(bool result) {
    cache_lookup_status_ = result;
    if (result) {
      ++num_callback_with_true_called_;
    } else {
      ++num_callback_with_false_called_;
    }
  }

  bool ExecuteGet(PropertyPage* page) {
    AbstractPropertyStoreGetCallback* callback = NULL;
    cache_property_store_.Get(
        kUrl,
        kOptionsSignatureHash,
        kCacheKeySuffix,
        cohort_list_,
        page,
        NewCallback(this, &CachePropertyStoreTest::ResultCallback),
        &callback);
    callback->DeleteWhenDone();
    return cache_lookup_status_;
  }

 protected:
  LRUCache lru_cache_;
  scoped_ptr<ThreadSystem> thread_system_;
  SimpleStats stats_;
  MockTimer timer_;
  CachePropertyStore cache_property_store_;
  PropertyCache property_cache_;
  const PropertyCache::Cohort* cohort_;
  PropertyCache::CohortVector cohort_list_;
  scoped_ptr<MockPropertyPage> page_;
  int num_callback_with_false_called_;
  int num_callback_with_true_called_;
  bool cache_lookup_status_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CachePropertyStoreTest);
};

TEST_F(CachePropertyStoreTest, TestNoResultAvailable) {
  EXPECT_FALSE(ExecuteGet(page_.get()));
  EXPECT_EQ(CacheInterface::kNotFound, page_->GetCacheState(cohort_));
  EXPECT_EQ(1, num_callback_with_false_called_);
  EXPECT_EQ(0, num_callback_with_true_called_);
}

TEST_F(CachePropertyStoreTest, TestResultAvailable) {
  PropertyCacheValues values;
  values.ParseFromString(kParsableContent);
  cache_property_store_.Put(
      kUrl,
      kOptionsSignatureHash,
      kCacheKeySuffix,
      cohort_,
      &values,
      NULL);
  EXPECT_TRUE(ExecuteGet(page_.get()));
  EXPECT_EQ(CacheInterface::kAvailable, page_->GetCacheState(cohort_));
  EXPECT_EQ(0, num_callback_with_false_called_);
  EXPECT_EQ(1, num_callback_with_true_called_);
}

TEST_F(CachePropertyStoreTest, TestResultAvailableButNonParsable) {
  SharedString put_buffer(kNonParsableContent);
  lru_cache_.Put(cache_property_store_.CacheKey(kUrl,
                                                kOptionsSignatureHash,
                                                kCacheKeySuffix,
                                                cohort_),
                 &put_buffer);
  EXPECT_FALSE(ExecuteGet(page_.get()));
  EXPECT_EQ(CacheInterface::kAvailable, page_->GetCacheState(cohort_));
  EXPECT_EQ(1, num_callback_with_false_called_);
  EXPECT_EQ(0, num_callback_with_true_called_);
}

TEST_F(CachePropertyStoreTest, TestMultipleCohorts) {
  PropertyCache::InitCohortStats(kCohortName2, &stats_);
  const PropertyCache::Cohort* cohort2 =
      property_cache_.AddCohort(kCohortName2);
  cache_property_store_.AddCohort(kCohortName2);
  MockPropertyPage page(thread_system_.get(),
                        &property_cache_,
                        kUrl,
                        kOptionsSignatureHash,
                        kCacheKeySuffix);
  property_cache_.Read(&page);
  PropertyCacheValues values;
  values.ParseFromString(kParsableContent);
  cohort_list_.push_back(cohort2);
  lru_cache_.ClearStats();
  EXPECT_FALSE(ExecuteGet(&page));

  EXPECT_EQ(0, lru_cache_.num_hits());
  EXPECT_EQ(2, lru_cache_.num_misses());
  EXPECT_EQ(0, lru_cache_.num_inserts());

  lru_cache_.ClearStats();
  // Insert the value for cohort1.
  cache_property_store_.Put(
      kUrl,
      kOptionsSignatureHash,
      kCacheKeySuffix,
      cohort_,
      &values,
      NULL);
  EXPECT_TRUE(ExecuteGet(&page));

  EXPECT_EQ(1, lru_cache_.num_hits());
  EXPECT_EQ(1, lru_cache_.num_misses());
  EXPECT_EQ(1, lru_cache_.num_inserts());

  lru_cache_.ClearStats();
  // Insert the value for cohort2.
  cache_property_store_.Put(
      kUrl,
      kOptionsSignatureHash,
      kCacheKeySuffix,
      cohort2,
      &values,
      NULL);
  EXPECT_TRUE(ExecuteGet(&page));

  EXPECT_EQ(2, lru_cache_.num_hits());
  EXPECT_EQ(0, lru_cache_.num_misses());
  EXPECT_EQ(1, lru_cache_.num_inserts());

  EXPECT_EQ(1, num_callback_with_false_called_);
  EXPECT_EQ(2, num_callback_with_true_called_);
}

TEST_F(CachePropertyStoreTest, TestMultipleCacheBackends) {
  // Create a second cache implementation.
  LRUCache second_cache(kMaxCacheSize);
  PropertyCache::InitCohortStats(kCohortName2, &stats_);
  const PropertyCache::Cohort* cohort2 =
      property_cache_.AddCohort(kCohortName2);
  cache_property_store_.AddCohortWithCache(kCohortName2, &second_cache);
  MockPropertyPage page(
      thread_system_.get(),
      &property_cache_,
      kUrl,
      kOptionsSignatureHash,
      kCacheKeySuffix);
  property_cache_.Read(&page);
  PropertyCacheValues values;
  values.ParseFromString(kParsableContent);
  lru_cache_.ClearStats();
  second_cache.ClearStats();
  // Insert the value for cohort1.
  cache_property_store_.Put(
      kUrl,
      kOptionsSignatureHash,
      kCacheKeySuffix,
      cohort_,
      &values,
      NULL);
  // Insert the value for cohort2.
  cache_property_store_.Put(
      kUrl,
      kOptionsSignatureHash,
      kCacheKeySuffix,
      cohort2,
      &values,
      NULL);
  cohort_list_.push_back(cohort2);
  // Get the value for cohort1 and cohort2.
  EXPECT_TRUE(ExecuteGet(&page));
  EXPECT_EQ(CacheInterface::kAvailable, page.GetCacheState(cohort_));
  EXPECT_EQ(CacheInterface::kAvailable, page.GetCacheState(cohort2));

  EXPECT_EQ(1, lru_cache_.num_hits());
  EXPECT_EQ(0, lru_cache_.num_misses());
  EXPECT_EQ(1, lru_cache_.num_inserts());

  EXPECT_EQ(1, second_cache.num_hits());
  EXPECT_EQ(0, second_cache.num_misses());
  EXPECT_EQ(1, second_cache.num_inserts());

  EXPECT_EQ(0, num_callback_with_false_called_);
  EXPECT_EQ(1, num_callback_with_true_called_);
}

TEST_F(CachePropertyStoreTest, TestPropertyCacheKeyMethod) {
  GoogleString cache_key = cache_property_store_.CacheKey(
      kUrl,
      kOptionsSignatureHash,
      kCacheKeySuffix,
      cohort_);
  GoogleString expected = StrCat(
      "test/",
      kUrl, "_",
      kOptionsSignatureHash,
      kCacheKeySuffix, "@",
      cohort_->name());
  EXPECT_EQ(expected, cache_key);
}

TEST_F(CachePropertyStoreTest, TestPutHandlesNonNullCallback) {
  PropertyCacheValues values;
  values.ParseFromString(kParsableContent);
  cache_property_store_.Put(
      kUrl,
      kOptionsSignatureHash,
      kCacheKeySuffix,
      cohort_,
      &values,
      NewCallback(this, &CachePropertyStoreTest::ResultCallback));
  EXPECT_EQ(0, num_callback_with_false_called_);
  EXPECT_EQ(1, num_callback_with_true_called_);
}

}  // namespace net_instaweb
