// 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 COMPONENTS_SQLITE_PROTO_KEY_VALUE_DATA_H_
#define COMPONENTS_SQLITE_PROTO_KEY_VALUE_DATA_H_

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

#include "base/bind.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/timer/timer.h"
#include "components/sqlite_proto/key_value_table.h"
#include "components/sqlite_proto/table_manager.h"

namespace sqlite_proto {

namespace internal {
// FakeCompare is a dummy comparator provided so that clients using
// KeyValueData<T> objects with unbounded-size caches need not
// specify the Compare template parameter, which is used exclusively
// for pruning the cache when it would exceed its size bound.
template <typename T>
struct FakeCompare {
  bool operator()(const T& unused_lhs, const T& unused_rhs) { return true; }
};
}  // namespace internal

// The class provides a synchronous access to the data backed by
// KeyValueTable<T>. The current implementation caches all the
// data in the memory. The cache size is limited by the |max_num_entries|
// parameter, using the Compare function to decide which entries should
// be evicted.
//
// NOTE: If the data store is larger than the maximum cache size, it
// will be pruned on construction to satisfy the size invariant specified
// by |max_num_entries|. If this is undesirable, set a sufficiently high
// |max_num_entries| (or pass |max_num_entries| = base::nullopt for
// unbounded size).
//
// InitializeOnDBSequence() must be called on the DB sequence of the
// TableManager. All other methods must be called on UI thread.
template <typename T, typename Compare = internal::FakeCompare<T>>
class KeyValueData {
 public:
  // Constructor. Parameters:
  // - |manager| provides an interface for scheduling database tasks for
  // execution on the database thread.
  // - |backend| provides the operations for updating and querying the
  // backing database (to be scheduled and executed using |manager|).
  // - |max_num_entries|, if given, caps the size of the in-memory cache;
  // the Compare template parameter requires a meaningful (in particular,
  // non-default) value iff max_num_entries is non-nullopt.
  // - |flush_delay| is the interval for which to gather writes and deletes
  // passing them through to the backing store; a value of zero will
  // pass writes and deletes through immediately.
  KeyValueData(scoped_refptr<TableManager> manager,
               KeyValueTable<T>* backend,
               base::Optional<size_t> max_num_entries,
               base::TimeDelta flush_delay);

  KeyValueData(const KeyValueData&) = delete;
  KeyValueData& operator=(const KeyValueData&) = delete;

  // Must be called on the provided TableManager's DB sequence
  // 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;

  // Returns a view of all the cached data. (The next write or delete may
  // invalidate this reference.)
  const std::map<std::string, T>& GetAllCached() { return *data_cache_; }

  // 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:
  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<TableManager> manager_;
  KeyValueTable<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 base::Optional<size_t> max_num_entries_;
  EntryCompare entry_compare_;

  SEQUENCE_CHECKER(sequence_checker_);
};

template <typename T, typename Compare>
KeyValueData<T, Compare>::KeyValueData(scoped_refptr<TableManager> manager,
                                       KeyValueTable<T>* backend,
                                       base::Optional<size_t> max_num_entries,
                                       base::TimeDelta flush_delay)
    : manager_(manager),
      backend_table_(backend),
      flush_delay_(flush_delay),
      max_num_entries_(max_num_entries) {}

template <typename T, typename Compare>
void KeyValueData<T, Compare>::InitializeOnDBSequence() {
  DCHECK(manager_->GetTaskRunner()->RunsTasksInCurrentSequence());
  auto data_map = std::make_unique<std::map<std::string, T>>();

  manager_->ExecuteDBTaskOnDBSequence(
      base::BindOnce(&KeyValueTable<T>::GetAllData, backend_table_->AsWeakPtr(),
                     data_map.get()));

  // To ensure invariant that data_cache_.size() <= max_num_entries_.
  std::vector<std::string> keys_to_delete;
  while (max_num_entries_.has_value() && data_map->size() > *max_num_entries_) {
    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.empty()) {
    manager_->ExecuteDBTaskOnDBSequence(base::BindOnce(
        &KeyValueTable<T>::DeleteData, backend_table_->AsWeakPtr(),
        std::vector<std::string>(keys_to_delete)));
  }

  data_cache_ = std::move(data_map);
}

template <typename T, typename Compare>
bool KeyValueData<T, Compare>::TryGetData(const std::string& key,
                                          T* data) const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  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 KeyValueData<T, Compare>::UpdateData(const std::string& key,
                                          const T& data) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(data_cache_);
  auto it = data_cache_->find(key);
  if (it == data_cache_->end()) {
    if (data_cache_->size() == max_num_entries_) {
      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,
                       &KeyValueData::FlushDataToDisk);
  }
}

template <typename T, typename Compare>
void KeyValueData<T, Compare>::DeleteData(
    const std::vector<std::string>& keys) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  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 KeyValueData<T, Compare>::DeleteAllData() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(data_cache_);
  data_cache_->clear();
  deferred_updates_.clear();
  // Delete all the content of the database immediately because it was requested
  // by user.
  manager_->ScheduleDBTask(FROM_HERE,
                           base::BindOnce(&KeyValueTable<T>::DeleteAllData,
                                          backend_table_->AsWeakPtr()));
}

template <typename T, typename Compare>
void KeyValueData<T, Compare>::FlushDataToDisk() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  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()) {
          manager_->ScheduleDBTask(
              FROM_HERE,
              base::BindOnce(&KeyValueTable<T>::UpdateData,
                             backend_table_->AsWeakPtr(), key, it->second));
        }
        break;
      }
      case DeferredOperation::kDelete:
        keys_to_delete.push_back(key);
    }
  }

  if (!keys_to_delete.empty()) {
    manager_->ScheduleDBTask(
        FROM_HERE, base::BindOnce(&KeyValueTable<T>::DeleteData,
                                  backend_table_->AsWeakPtr(), keys_to_delete));
  }

  deferred_updates_.clear();
}

}  // namespace sqlite_proto

#endif  // COMPONENTS_SQLITE_PROTO_KEY_VALUE_DATA_H_
