// Copyright 2017 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.

#ifndef CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_
#define CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_

#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/timer/timer.h"
#include "chrome/browser/predictors/glowplug_key_value_table.h"
#include "chrome/browser/predictors/resource_prefetch_predictor_tables.h"
#include "content/public/browser/browser_thread.h"

class PredictorsHandler;

namespace predictors {

// The class provides a synchronous access to the data backed by
// GlowplugKeyValueTable<T>. The current implementation caches all the data in
// the memory. The cache size is limited by max_size parameter using Compare
// function to decide which entry should be evicted.
//
// InitializeOnDBSequence() must be called on the DB sequence of the
// ResourcePrefetchPredictorTables. All other methods must be called on UI
// thread.
template <typename T, typename Compare>
class GlowplugKeyValueData {
 public:
  GlowplugKeyValueData(scoped_refptr<ResourcePrefetchPredictorTables> tables,
                       GlowplugKeyValueTable<T>* backend,
                       size_t max_size,
                       base::TimeDelta flush_delay);

  // Must be called on the DB sequence of the ResourcePrefetchPredictorTables
  // before calling all other methods.
  void InitializeOnDBSequence();

  // Assigns data associated with the |key| to |data|. Returns true iff the
  // |key| exists, false otherwise. |data| pointer may be nullptr to get the
  // return value only.
  bool TryGetData(const std::string& key, T* data) const;

  // Assigns data associated with the |key| to |data|.
  void UpdateData(const std::string& key, const T& data);

  // Deletes data associated with the |keys| from the database.
  void DeleteData(const std::vector<std::string>& keys);

  // Deletes all entries from the database.
  void DeleteAllData();

 private:
  friend class ResourcePrefetchPredictorTest;
  friend class ::PredictorsHandler;

  struct EntryCompare : private Compare {
    bool operator()(const std::pair<std::string, T>& lhs,
                    const std::pair<std::string, T>& rhs) {
      return Compare::operator()(lhs.second, rhs.second);
    }
  };

  enum class DeferredOperation { kUpdate, kDelete };

  void FlushDataToDisk();

  scoped_refptr<ResourcePrefetchPredictorTables> tables_;
  GlowplugKeyValueTable<T>* backend_table_;
  std::unique_ptr<std::map<std::string, T>> data_cache_;
  std::unordered_map<std::string, DeferredOperation> deferred_updates_;
  base::RepeatingTimer flush_timer_;
  const base::TimeDelta flush_delay_;
  const size_t max_size_;
  EntryCompare entry_compare_;

  DISALLOW_COPY_AND_ASSIGN(GlowplugKeyValueData);
};

template <typename T, typename Compare>
GlowplugKeyValueData<T, Compare>::GlowplugKeyValueData(
    scoped_refptr<ResourcePrefetchPredictorTables> tables,
    GlowplugKeyValueTable<T>* backend,
    size_t max_size,
    base::TimeDelta flush_delay)
    : tables_(tables),
      backend_table_(backend),
      flush_delay_(flush_delay),
      max_size_(max_size) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}

template <typename T, typename Compare>
void GlowplugKeyValueData<T, Compare>::InitializeOnDBSequence() {
  DCHECK(tables_->GetTaskRunner()->RunsTasksInCurrentSequence());
  auto data_map = std::make_unique<std::map<std::string, T>>();
  tables_->ExecuteDBTaskOnDBSequence(
      base::BindOnce(&GlowplugKeyValueTable<T>::GetAllData,
                     base::Unretained(backend_table_), data_map.get()));

  // To ensure invariant that data_cache_.size() <= max_size_.
  std::vector<std::string> keys_to_delete;
  while (data_map->size() > max_size_) {
    auto entry_to_delete =
        std::min_element(data_map->begin(), data_map->end(), entry_compare_);
    keys_to_delete.emplace_back(entry_to_delete->first);
    data_map->erase(entry_to_delete);
  }
  if (keys_to_delete.size() > 0) {
    tables_->ExecuteDBTaskOnDBSequence(base::BindOnce(
        &GlowplugKeyValueTable<T>::DeleteData, base::Unretained(backend_table_),
        std::vector<std::string>(keys_to_delete)));
  }

  data_cache_ = std::move(data_map);
}

template <typename T, typename Compare>
bool GlowplugKeyValueData<T, Compare>::TryGetData(const std::string& key,
                                                  T* data) const {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(data_cache_);
  auto it = data_cache_->find(key);
  if (it == data_cache_->end())
    return false;

  if (data)
    *data = it->second;
  return true;
}

template <typename T, typename Compare>
void GlowplugKeyValueData<T, Compare>::UpdateData(const std::string& key,
                                                  const T& data) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(data_cache_);
  auto it = data_cache_->find(key);
  if (it == data_cache_->end()) {
    if (data_cache_->size() == max_size_) {
      auto entry_to_delete = std::min_element(
          data_cache_->begin(), data_cache_->end(), entry_compare_);
      deferred_updates_[entry_to_delete->first] = DeferredOperation::kDelete;
      data_cache_->erase(entry_to_delete);
    }
    data_cache_->emplace(key, data);
  } else {
    it->second = data;
  }
  deferred_updates_[key] = DeferredOperation::kUpdate;

  if (flush_delay_.is_zero()) {
    // Flush immediately, only for tests.
    FlushDataToDisk();
  } else if (!flush_timer_.IsRunning()) {
    flush_timer_.Start(FROM_HERE, flush_delay_, this,
                       &GlowplugKeyValueData::FlushDataToDisk);
  }
}

template <typename T, typename Compare>
void GlowplugKeyValueData<T, Compare>::DeleteData(
    const std::vector<std::string>& keys) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(data_cache_);
  for (const std::string& key : keys) {
    if (data_cache_->erase(key))
      deferred_updates_[key] = DeferredOperation::kDelete;
  }

  // Run all deferred updates immediately because it was requested by user.
  if (!deferred_updates_.empty())
    FlushDataToDisk();
}

template <typename T, typename Compare>
void GlowplugKeyValueData<T, Compare>::DeleteAllData() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(data_cache_);
  data_cache_->clear();
  deferred_updates_.clear();
  // Delete all the content of the database immediately because it was requested
  // by user.
  tables_->ScheduleDBTask(
      FROM_HERE, base::BindOnce(&GlowplugKeyValueTable<T>::DeleteAllData,
                                base::Unretained(backend_table_)));
}

template <typename T, typename Compare>
void GlowplugKeyValueData<T, Compare>::FlushDataToDisk() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (deferred_updates_.empty())
    return;

  std::vector<std::string> keys_to_delete;
  for (const auto& entry : deferred_updates_) {
    const std::string& key = entry.first;
    switch (entry.second) {
      case DeferredOperation::kUpdate: {
        auto it = data_cache_->find(key);
        if (it != data_cache_->end()) {
          tables_->ScheduleDBTask(
              FROM_HERE, base::BindOnce(&GlowplugKeyValueTable<T>::UpdateData,
                                        base::Unretained(backend_table_), key,
                                        it->second));
        }
        break;
      }
      case DeferredOperation::kDelete:
        keys_to_delete.push_back(key);
    }
  }

  if (!keys_to_delete.empty()) {
    tables_->ScheduleDBTask(
        FROM_HERE,
        base::BindOnce(&GlowplugKeyValueTable<T>::DeleteData,
                       base::Unretained(backend_table_), keys_to_delete));
  }

  deferred_updates_.clear();
}

}  // namespace predictors

#endif  // CHROME_BROWSER_PREDICTORS_GLOWPLUG_KEY_VALUE_DATA_H_
