/*
 * 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: jmarantz@google.com (Joshua Marantz)

#include "pagespeed/kernel/cache/compressed_cache.h"

#include <cstddef>

#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/shared_string.h"
#include "pagespeed/kernel/base/stack_buffer.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/cache/cache_interface.h"
#include "pagespeed/kernel/cache/cache_test_base.h"
#include "pagespeed/kernel/cache/lru_cache.h"
#include "pagespeed/kernel/util/platform.h"
#include "pagespeed/kernel/util/simple_random.h"
#include "pagespeed/kernel/util/simple_stats.h"

namespace net_instaweb {

namespace {
const size_t kMaxSize = 10*kStackBufferSize;
}

class CompressedCacheTest : public CacheTestBase {
 protected:
  CompressedCacheTest()
      : lru_cache_(new LRUCache(kMaxSize)),
        thread_system_(Platform::CreateThreadSystem()),
        stats_(thread_system_.get()),
        random_(thread_system_->NewMutex()) {
    CompressedCache::InitStats(&stats_);
    compressed_cache_.reset(new CompressedCache(lru_cache_.get(), &stats_));
  }

  // Get the raw compressed buffer out directly out of the LRU cache.
  GoogleString GetRawValue(const GoogleString& key) {
    Callback* callback = InitiateGet(lru_cache_.get(), key);
    callback->Wait();
    EXPECT_TRUE(callback->called());
    GoogleString ret;
    callback->value()->Value().CopyToString(&ret);
    PostOpCleanup();
    return ret;
  }

  virtual CacheInterface* Cache() { return compressed_cache_.get(); }

  GoogleMessageHandler handler_;
  scoped_ptr<LRUCache> lru_cache_;
  scoped_ptr<ThreadSystem> thread_system_;
  SimpleStats stats_;
  scoped_ptr<CompressedCache> compressed_cache_;
  SimpleRandom random_;
};

// Simple flow of putting in an item, getting it, deleting it.
TEST_F(CompressedCacheTest, PutGetDelete) {
  CheckPut("Name", "Value");
  CheckGet("Name", "Value");
  CheckNotFound("Another Name");

  CheckPut("Name", "NewValue");
  CheckGet("Name", "NewValue");

  EXPECT_LT(0, lru_cache_->size_bytes());

  Cache()->Delete("Name");
  CheckNotFound("Name");

  EXPECT_EQ(0, lru_cache_->size_bytes());
  EXPECT_EQ(0, compressed_cache_->CorruptPayloads());
}

TEST_F(CompressedCacheTest, SizeTest) {
  GoogleString value(3 * kStackBufferSize, 'a');
  CheckPut("Name", value);
  CheckGet("Name", value);
  EXPECT_GT(100, lru_cache_->size_bytes());
  EXPECT_GT(100, compressed_cache_->CompressedSize());
  EXPECT_EQ(static_cast<int64>(value.size()),
            compressed_cache_->OriginalSize());
  EXPECT_EQ(0, compressed_cache_->CorruptPayloads());
}

TEST_F(CompressedCacheTest, LargeDataHighEntropy) {
  // The internals of the deflater work using kStackBufferSize, so we
  // want to make sure that we test with strings large enough to cover
  // the corner cases at the boundaries.  Note that in SizeTest above,
  // the input spills over kStackBufferSize, but the output doesn't
  // because that long string of 'a' compresses very well.
  GoogleString value = random_.GenerateHighEntropyString(5 * kStackBufferSize);
  CheckPut("Name", value);
  CheckGet("Name", value);
  EXPECT_LT(2*kStackBufferSize, lru_cache_->size_bytes());
  EXPECT_EQ(0, compressed_cache_->CorruptPayloads());
}

TEST_F(CompressedCacheTest, EmptyValue) {
  CheckPut("key", "");
  CheckGet("key", "");
  EXPECT_EQ(0, compressed_cache_->CorruptPayloads());
}

// Test a few patterns of corruption.  We do this by messing with the
// compressed bytes directly in the lru_cache_.

TEST_F(CompressedCacheTest, PhysicallyEmptyValue) {
  CheckPut(lru_cache_.get(), "key", "");

  // The physical value must have a signature written by
  // compressed_cache.cc, otherwise it reports a miss due to
  // corruption.
  CheckNotFound("key");
  EXPECT_EQ(1, compressed_cache_->CorruptPayloads());
}

TEST_F(CompressedCacheTest, TotalGarbage) {
  CheckPut(lru_cache_.get(), "key", "garbage");
  CheckNotFound("key");
  EXPECT_EQ(1, compressed_cache_->CorruptPayloads());
}

TEST_F(CompressedCacheTest, CrapAtEnd) {
  CheckPut("key", "garbage");
  GoogleString raw_value = GetRawValue("key");
  // Appending 'crap' to the raw value means we can no longer
  // decompress, so we expect a miss and a corruption count.
  StrAppend(&raw_value, "crap");
  lru_cache_->PutSwappingString("key", &raw_value);
  CheckNotFound("key");
  EXPECT_EQ(1, compressed_cache_->CorruptPayloads());
}

TEST_F(CompressedCacheTest, CrapAtBeginning) {
  CheckPut("key", "garbage");
  GoogleString raw_value = GetRawValue("key");
  raw_value.insert(0, "crap");
  lru_cache_->PutSwappingString("key", &raw_value);
  CheckNotFound("key");
  EXPECT_EQ(1, compressed_cache_->CorruptPayloads());
}

TEST_F(CompressedCacheTest, InsertInMiddle) {
  // Make sure that the corruption is detected multiple stack-buffers
  // into the compressed string.
  GoogleString value = random_.GenerateHighEntropyString(5 * kStackBufferSize);
  CheckPut("key", value);
  GoogleString raw_value = GetRawValue("key");
  raw_value.insert(raw_value.size() / 2, "crap");
  lru_cache_->PutSwappingString("key", &raw_value);
  CheckNotFound("key");
  EXPECT_EQ(1, compressed_cache_->CorruptPayloads());
}

TEST_F(CompressedCacheTest, RemoveOneByteFromMiddle) {
  GoogleString value = random_.GenerateHighEntropyString(5 * kStackBufferSize);
  CheckPut("key", value);
  GoogleString raw_value = GetRawValue("key");
  raw_value.erase(raw_value.size() / 2, 1);
  lru_cache_->PutSwappingString("key", &raw_value);
  CheckNotFound("key");
  EXPECT_EQ(1, compressed_cache_->CorruptPayloads());
}

}  // namespace net_instaweb
