// Copyright (c) 2012 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 "content/renderer/dom_storage/dom_storage_cached_area.h"

#include <limits>

#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/common/dom_storage/dom_storage_map.h"
#include "content/renderer/dom_storage/dom_storage_proxy.h"
#include "third_party/WebKit/public/platform/scheduler/web_main_thread_scheduler.h"

namespace content {

DOMStorageCachedArea::DOMStorageCachedArea(
    const std::string& namespace_id,
    const GURL& origin,
    DOMStorageProxy* proxy,
    blink::scheduler::RendererScheduler* renderer_scheduler)
    : ignore_all_mutations_(false),
      namespace_id_(namespace_id),
      origin_(origin),
      proxy_(proxy),
      renderer_scheduler_(renderer_scheduler),
      weak_factory_(this) {}

DOMStorageCachedArea::~DOMStorageCachedArea() {}

unsigned DOMStorageCachedArea::GetLength(int connection_id) {
  PrimeIfNeeded(connection_id);
  return map_->Length();
}

base::NullableString16 DOMStorageCachedArea::GetKey(int connection_id,
                                                    unsigned index) {
  PrimeIfNeeded(connection_id);
  return map_->Key(index);
}

base::NullableString16 DOMStorageCachedArea::GetItem(
    int connection_id,
    const base::string16& key) {
  PrimeIfNeeded(connection_id);
  return map_->GetItem(key);
}

bool DOMStorageCachedArea::SetItem(int connection_id,
                                   const base::string16& key,
                                   const base::string16& value,
                                   const GURL& page_url) {
  // A quick check to reject obviously overbudget items to avoid
  // the priming the cache.
  if ((key.length() + value.length()) * sizeof(base::char16) >
      kPerStorageAreaQuota)
    return false;

  PrimeIfNeeded(connection_id);
  base::NullableString16 old_value;
#if !defined(OS_ANDROID)
  if (!map_->SetItem(key, value, nullptr))
    return false;
#else
  // The old value is only used on Android when the cache stores only the keys.
  // Do not send old value on other platforms.
  // TODO(ssid): Clear this value when values are stored in the browser cache on
  // Android, crbug.com/743187.
  if (!map_->SetItem(key, value, &old_value))
    return false;
#endif  // !defined(OS_ANDROID)

  // Ignore mutations to 'key' until OnSetItemComplete.
  blink::WebScopedVirtualTimePauser virtual_time_pauser =
      renderer_scheduler_->CreateWebScopedVirtualTimePauser();
  virtual_time_pauser.PauseVirtualTime(true);
  ignore_key_mutations_[key]++;
  proxy_->SetItem(connection_id, key, value, old_value, page_url,
                  base::BindOnce(&DOMStorageCachedArea::OnSetItemComplete,
                                 weak_factory_.GetWeakPtr(), key,
                                 std::move(virtual_time_pauser)));
  return true;
}

void DOMStorageCachedArea::RemoveItem(int connection_id,
                                      const base::string16& key,
                                      const GURL& page_url) {
  PrimeIfNeeded(connection_id);
  base::string16 old_value;
#if !defined(OS_ANDROID)
  if (!map_->RemoveItem(key, nullptr))
    return;
#else
  // The old value is only used on Android when the cache stores only the keys.
  // Do not send old value on other platforms.
  if (!map_->RemoveItem(key, &old_value))
    return;
#endif

  // Ignore mutations to 'key' until OnRemoveItemComplete.
  blink::WebScopedVirtualTimePauser virtual_time_pauser =
      renderer_scheduler_->CreateWebScopedVirtualTimePauser();
  virtual_time_pauser.PauseVirtualTime(true);
  ignore_key_mutations_[key]++;
  proxy_->RemoveItem(connection_id, key,
                     base::NullableString16(old_value, false), page_url,
                     base::BindOnce(&DOMStorageCachedArea::OnRemoveItemComplete,
                                    weak_factory_.GetWeakPtr(), key,
                                    std::move(virtual_time_pauser)));
}

void DOMStorageCachedArea::Clear(int connection_id, const GURL& page_url) {
  // No need to prime the cache in this case.
  Reset();
  map_ = new DOMStorageMap(kPerStorageAreaQuota);

  // Ignore all mutations until OnClearComplete time.
  blink::WebScopedVirtualTimePauser virtual_time_pauser =
      renderer_scheduler_->CreateWebScopedVirtualTimePauser();
  virtual_time_pauser.PauseVirtualTime(true);
  ignore_all_mutations_ = true;
  proxy_->ClearArea(connection_id, page_url,
                    base::BindOnce(&DOMStorageCachedArea::OnClearComplete,
                                   weak_factory_.GetWeakPtr(),
                                   std::move(virtual_time_pauser)));
}

void DOMStorageCachedArea::ApplyMutation(
    const base::NullableString16& key,
    const base::NullableString16& new_value) {
  if (!map_.get() || ignore_all_mutations_)
    return;

  if (key.is_null()) {
    // It's a clear event.
    scoped_refptr<DOMStorageMap> old = map_;
    map_ = new DOMStorageMap(kPerStorageAreaQuota);

    // We have to retain local additions which happened after this
    // clear operation from another process.
    std::map<base::string16, int>::iterator iter =
        ignore_key_mutations_.begin();
    while (iter != ignore_key_mutations_.end()) {
      base::NullableString16 value = old->GetItem(iter->first);
      if (!value.is_null()) {
        map_->SetItem(iter->first, value.string(), nullptr);
      }
      ++iter;
    }
    return;
  }

  // We have to retain local changes.
  if (should_ignore_key_mutation(key.string()))
    return;

  if (new_value.is_null()) {
    // It's a remove item event.
    map_->RemoveItem(key.string(), nullptr);
    return;
  }

  // It's a set item event.
  // We turn off quota checking here to accomodate the over budget
  // allowance that's provided in the browser process.
  map_->set_quota(std::numeric_limits<int32_t>::max());
  map_->SetItem(key.string(), new_value.string(), nullptr);
  map_->set_quota(kPerStorageAreaQuota);
}

void DOMStorageCachedArea::Prime(int connection_id) {
  DCHECK(!map_.get());

  // The LoadArea method is actually synchronous, but we have to
  // wait for an asyncly delivered message to know when incoming
  // mutation events should be applied. Our valuemap is plucked
  // from ipc stream out of order, mutations in front if it need
  // to be ignored.

  // Ignore all mutations until OnLoadComplete time.
  ignore_all_mutations_ = true;
  DOMStorageValuesMap values;
  base::TimeTicks before = base::TimeTicks::Now();
  proxy_->LoadArea(connection_id, &values,
                   base::BindOnce(&DOMStorageCachedArea::OnLoadComplete,
                                  weak_factory_.GetWeakPtr()));
  base::TimeDelta time_to_prime = base::TimeTicks::Now() - before;
  // Keeping this histogram named the same (without the ForRenderer suffix)
  // to maintain histogram continuity.
  UMA_HISTOGRAM_TIMES("LocalStorage.TimeToPrimeLocalStorage",
                      time_to_prime);
  map_ = new DOMStorageMap(kPerStorageAreaQuota);
  map_->SwapValues(&values);

  size_t local_storage_size_kb = map_->storage_used() / 1024;
  // Track localStorage size, from 0-6MB. Note that the maximum size should be
  // 5MB, but we add some slop since we want to make sure the max size is always
  // above what we see in practice, since histograms can't change.
  UMA_HISTOGRAM_CUSTOM_COUNTS("LocalStorage.RendererLocalStorageSizeInKB",
                              local_storage_size_kb,
                              1, 6 * 1024, 50);
  if (local_storage_size_kb < 100) {
    UMA_HISTOGRAM_TIMES(
        "LocalStorage.RendererTimeToPrimeLocalStorageUnder100KB",
        time_to_prime);
  } else if (local_storage_size_kb < 1000) {
    UMA_HISTOGRAM_TIMES(
        "LocalStorage.RendererTimeToPrimeLocalStorage100KBTo1MB",
        time_to_prime);
  } else {
    UMA_HISTOGRAM_TIMES(
        "LocalStorage.RendererTimeToPrimeLocalStorage1MBTo5MB",
        time_to_prime);
  }
}

void DOMStorageCachedArea::Reset() {
  map_ = nullptr;
  weak_factory_.InvalidateWeakPtrs();
  ignore_key_mutations_.clear();
  ignore_all_mutations_ = false;
}

void DOMStorageCachedArea::OnLoadComplete(bool success) {
  DCHECK(success);
  DCHECK(ignore_all_mutations_);
  ignore_all_mutations_ = false;
}

void DOMStorageCachedArea::OnSetItemComplete(const base::string16& key,
                                             blink::WebScopedVirtualTimePauser,
                                             bool success) {
  if (!success) {
    Reset();
    return;
  }
  std::map<base::string16, int>::iterator found =
      ignore_key_mutations_.find(key);
  DCHECK(found != ignore_key_mutations_.end());
  if (--found->second == 0)
    ignore_key_mutations_.erase(found);
}

void DOMStorageCachedArea::OnRemoveItemComplete(
    const base::string16& key,
    blink::WebScopedVirtualTimePauser,
    bool success) {
  DCHECK(success);
  std::map<base::string16, int>::iterator found =
      ignore_key_mutations_.find(key);
  DCHECK(found != ignore_key_mutations_.end());
  if (--found->second == 0)
    ignore_key_mutations_.erase(found);
}

void DOMStorageCachedArea::OnClearComplete(blink::WebScopedVirtualTimePauser,
                                           bool success) {
  DCHECK(success);
  DCHECK(ignore_all_mutations_);
  ignore_all_mutations_ = false;
}

}  // namespace content
