// Copyright (c) 2011 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/message_loop/message_loop.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::Time;
using base::TimeDelta;
using content::BrowserThread;
using WebKit::WebCache;

class WebCacheManagerTest : public testing::Test {
 protected:
  typedef WebCacheManager::StatsMap StatsMap;
  typedef WebCacheManager::Allocation Allocation;
  typedef WebCacheManager::AllocationStrategy AllocationStrategy;

  static const int kRendererID;
  static const int kRendererID2;
  static const WebCache::UsageStats kStats;
  static const WebCache::UsageStats kStats2;

  WebCacheManagerTest()
      : ui_thread_(BrowserThread::UI, &message_loop_) {
  }

  // Thunks to access protected members of WebCacheManager
  static std::map<int, WebCacheManager::RendererInfo>& stats(
        WebCacheManager* h) {
    return h->stats_;
  }

  static void SimulateInactivity(WebCacheManager* h, int renderer_id) {
    stats(h)[renderer_id].access = Time::Now() - TimeDelta::FromMinutes(
        WebCacheManager::kRendererInactiveThresholdMinutes);
    h->FindInactiveRenderers();
  }

  static std::set<int>& active_renderers(WebCacheManager* h) {
    return h->active_renderers_;
  }
  static std::set<int>& inactive_renderers(WebCacheManager* h) {
    return h->inactive_renderers_;
  }
  static void GatherStats(WebCacheManager* h,
                          std::set<int> renderers,
                          WebCache::UsageStats* stats) {
    h->GatherStats(renderers, stats);
  }
  static size_t GetSize(int tactic,
                        const WebCache::UsageStats& stats) {
    return WebCacheManager::GetSize(
        static_cast<WebCacheManager::AllocationTactic>(tactic), stats);
  }
  static bool AttemptTactic(WebCacheManager* h,
                            int active_tactic,
                            const WebCache::UsageStats& active_stats,
                            int inactive_tactic,
                            const WebCache::UsageStats& inactive_stats,
                            std::list< std::pair<int,size_t> >* strategy) {
    return h->AttemptTactic(
        static_cast<WebCacheManager::AllocationTactic>(active_tactic),
        active_stats,
        static_cast<WebCacheManager::AllocationTactic>(inactive_tactic),
        inactive_stats,
        strategy);
  }
  static void AddToStrategy(WebCacheManager* h,
                            std::set<int> renderers,
                            int tactic,
                            size_t extra_bytes_to_allocate,
                            std::list< std::pair<int,size_t> >* strategy) {
    h->AddToStrategy(renderers,
                     static_cast<WebCacheManager::AllocationTactic>(tactic),
                     extra_bytes_to_allocate,
                     strategy);
  }

  enum {
    DIVIDE_EVENLY = WebCacheManager::DIVIDE_EVENLY,
    KEEP_CURRENT_WITH_HEADROOM = WebCacheManager::KEEP_CURRENT_WITH_HEADROOM,
    KEEP_CURRENT = WebCacheManager::KEEP_CURRENT,
    KEEP_LIVE_WITH_HEADROOM = WebCacheManager::KEEP_LIVE_WITH_HEADROOM,
    KEEP_LIVE = WebCacheManager::KEEP_LIVE,
  };

  WebCacheManager* manager() { return &manager_; }

 private:
  WebCacheManager manager_;
  base::MessageLoop message_loop_;
  content::TestBrowserThread ui_thread_;
};

// static
const int WebCacheManagerTest::kRendererID = 146;

// static
const int WebCacheManagerTest::kRendererID2 = 245;

// static
const WebCache::UsageStats WebCacheManagerTest::kStats = {
    0,
    1024 * 1024,
    1024 * 1024,
    256 * 1024,
    512,
  };

// static
const WebCache::UsageStats WebCacheManagerTest::kStats2 = {
    0,
    2 * 1024 * 1024,
    2 * 1024 * 1024,
    2 * 256 * 1024,
    2 * 512,
  };

static bool operator==(const WebCache::UsageStats& lhs,
                       const WebCache::UsageStats& rhs) {
  return !::memcmp(&lhs, &rhs, sizeof(WebCache::UsageStats));
}

TEST_F(WebCacheManagerTest, AddRemoveRendererTest) {
  EXPECT_EQ(0U, active_renderers(manager()).size());
  EXPECT_EQ(0U, inactive_renderers(manager()).size());

  manager()->Add(kRendererID);
  EXPECT_EQ(1U, active_renderers(manager()).count(kRendererID));
  EXPECT_EQ(0U, inactive_renderers(manager()).count(kRendererID));

  manager()->Remove(kRendererID);
  EXPECT_EQ(0U, active_renderers(manager()).size());
  EXPECT_EQ(0U, inactive_renderers(manager()).size());
}

TEST_F(WebCacheManagerTest, ActiveInactiveTest) {
  manager()->Add(kRendererID);

  manager()->ObserveActivity(kRendererID);
  EXPECT_EQ(1U, active_renderers(manager()).count(kRendererID));
  EXPECT_EQ(0U, inactive_renderers(manager()).count(kRendererID));

  SimulateInactivity(manager(), kRendererID);
  EXPECT_EQ(0U, active_renderers(manager()).count(kRendererID));
  EXPECT_EQ(1U, inactive_renderers(manager()).count(kRendererID));

  manager()->ObserveActivity(kRendererID);
  EXPECT_EQ(1U, active_renderers(manager()).count(kRendererID));
  EXPECT_EQ(0U, inactive_renderers(manager()).count(kRendererID));

  manager()->Remove(kRendererID);
}

TEST_F(WebCacheManagerTest, ObserveStatsTest) {
  manager()->Add(kRendererID);

  EXPECT_EQ(1U, stats(manager()).size());

  manager()->ObserveStats(kRendererID, kStats);

  EXPECT_EQ(1U, stats(manager()).size());
  EXPECT_TRUE(kStats == stats(manager())[kRendererID]);

  manager()->Remove(kRendererID);
}

TEST_F(WebCacheManagerTest, SetGlobalSizeLimitTest) {
  size_t limit = manager()->GetDefaultGlobalSizeLimit();
  manager()->SetGlobalSizeLimit(limit);
  EXPECT_EQ(limit, manager()->global_size_limit());

  manager()->SetGlobalSizeLimit(0);
  EXPECT_EQ(0U, manager()->global_size_limit());
}

TEST_F(WebCacheManagerTest, GatherStatsTest) {
  manager()->Add(kRendererID);
  manager()->Add(kRendererID2);

  manager()->ObserveStats(kRendererID, kStats);
  manager()->ObserveStats(kRendererID2, kStats2);

  std::set<int> renderer_set;
  renderer_set.insert(kRendererID);

  WebCache::UsageStats stats;
  GatherStats(manager(), renderer_set, &stats);

  EXPECT_TRUE(kStats == stats);

  renderer_set.insert(kRendererID2);
  GatherStats(manager(), renderer_set, &stats);

  WebCache::UsageStats expected_stats = kStats;
  expected_stats.minDeadCapacity += kStats2.minDeadCapacity;
  expected_stats.maxDeadCapacity += kStats2.maxDeadCapacity;
  expected_stats.capacity += kStats2.capacity;
  expected_stats.liveSize += kStats2.liveSize;
  expected_stats.deadSize += kStats2.deadSize;

  EXPECT_TRUE(expected_stats == stats);

  manager()->Remove(kRendererID);
  manager()->Remove(kRendererID2);
}

TEST_F(WebCacheManagerTest, GetSizeTest) {
  EXPECT_EQ(0U, GetSize(DIVIDE_EVENLY, kStats));
  EXPECT_LT(256 * 1024u + 512, GetSize(KEEP_CURRENT_WITH_HEADROOM, kStats));
  EXPECT_EQ(256 * 1024u + 512, GetSize(KEEP_CURRENT, kStats));
  EXPECT_LT(256 * 1024u, GetSize(KEEP_LIVE_WITH_HEADROOM, kStats));
  EXPECT_EQ(256 * 1024u, GetSize(KEEP_LIVE, kStats));
}

TEST_F(WebCacheManagerTest, AttemptTacticTest) {
  manager()->Add(kRendererID);
  manager()->Add(kRendererID2);

  manager()->ObserveActivity(kRendererID);
  SimulateInactivity(manager(), kRendererID2);

  manager()->ObserveStats(kRendererID, kStats);
  manager()->ObserveStats(kRendererID2, kStats2);

  manager()->SetGlobalSizeLimit(kStats.liveSize + kStats.deadSize +
                        kStats2.liveSize + kStats2.deadSize/2);

  AllocationStrategy strategy;

  EXPECT_FALSE(AttemptTactic(manager(),
                             KEEP_CURRENT,
                             kStats,
                             KEEP_CURRENT,
                             kStats2,
                             &strategy));
  EXPECT_TRUE(strategy.empty());

  EXPECT_TRUE(AttemptTactic(manager(),
                            KEEP_CURRENT,
                            kStats,
                            KEEP_LIVE,
                            kStats2,
                            &strategy));
  EXPECT_EQ(2U, strategy.size());

  AllocationStrategy::iterator iter = strategy.begin();
  while (iter != strategy.end()) {
    if (iter->first == kRendererID)
      EXPECT_LE(kStats.liveSize + kStats.deadSize, iter->second);
    else if (iter->first == kRendererID2)
      EXPECT_LE(kStats2.liveSize, iter->second);
    else
      ADD_FAILURE();   // Unexpected entry in strategy.
    ++iter;
  }

  manager()->Remove(kRendererID);
  manager()->Remove(kRendererID2);
}

TEST_F(WebCacheManagerTest, AddToStrategyTest) {
  manager()->Add(kRendererID);
  manager()->Add(kRendererID2);

  std::set<int> renderer_set;
  renderer_set.insert(kRendererID);
  renderer_set.insert(kRendererID2);

  manager()->ObserveStats(kRendererID, kStats);
  manager()->ObserveStats(kRendererID2, kStats2);

  const size_t kExtraBytesToAllocate = 10 * 1024;

  AllocationStrategy strategy;
  AddToStrategy(manager(),
                renderer_set,
                KEEP_CURRENT,
                kExtraBytesToAllocate,
                &strategy);

  EXPECT_EQ(2U, strategy.size());

  size_t total_bytes = 0;
  AllocationStrategy::iterator iter = strategy.begin();
  while (iter != strategy.end()) {
    total_bytes += iter->second;

    if (iter->first == kRendererID)
      EXPECT_LE(kStats.liveSize + kStats.deadSize, iter->second);
    else if (iter->first == kRendererID2)
      EXPECT_LE(kStats2.liveSize + kStats2.deadSize, iter->second);
    else
      ADD_FAILURE();  // Unexpected entry in strategy.
    ++iter;
  }

  size_t expected_total_bytes = kExtraBytesToAllocate +
                                kStats.liveSize + kStats.deadSize +
                                kStats2.liveSize + kStats2.deadSize;

  EXPECT_GE(expected_total_bytes, total_bytes);

  manager()->Remove(kRendererID);
  manager()->Remove(kRendererID2);
}
