// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_IMPL_H_
#define COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_IMPL_H_

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

#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/task/sequenced_task_runner.h"
#include "components/leveldb_proto/internal/proto_database_selector.h"
#include "components/leveldb_proto/internal/shared_proto_database.h"
#include "components/leveldb_proto/internal/shared_proto_database_provider.h"
#include "components/leveldb_proto/public/proto_database.h"
#include "components/leveldb_proto/public/shared_proto_database_client_list.h"

namespace google {
namespace protobuf {
class MessageLite;
}  // namespace protobuf
}  // namespace google

namespace leveldb_proto {

// Update transactions happen on background task runner and callback runs on the
// client task runner.
void COMPONENT_EXPORT(LEVELDB_PROTO) RunUpdateCallback(
    scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
    Callbacks::UpdateCallback callback,
    bool success);

// Load transactions happen on background task runner. The loaded keys need to
// be given to clients on client task runner.
void COMPONENT_EXPORT(LEVELDB_PROTO) RunLoadKeysCallback(
    scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
    Callbacks::LoadKeysCallback callback,
    bool success,
    std::unique_ptr<KeyVector> keys);

// Helper to run destroy callback on the client task runner.
void COMPONENT_EXPORT(LEVELDB_PROTO) RunDestroyCallback(
    scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
    Callbacks::DestroyCallback callback,
    bool success);

// The ProtoDatabaseImpl<T> implements a ProtoDatabase<T> instance, and allows
// the underlying ProtoDatabase<T> implementation to change without users of the
// wrapper needing to know.
// This allows clients to request a DB instance without knowing whether or not
// it's a UniqueProtoDatabase or a SharedProtoDatabaseClient.
template <typename P, typename T = P>
class ProtoDatabaseImpl : public ProtoDatabase<P, T> {
 public:
  // Force usage of unique db.
  ProtoDatabaseImpl(
      ProtoDbType db_type,
      const base::FilePath& db_dir,
      const scoped_refptr<base::SequencedTaskRunner>& task_runner);

  // Internal implementation is free to choose between unique and shared
  // database to use here (transparently).
  ProtoDatabaseImpl(ProtoDbType db_type,
                    const base::FilePath& db_dir,
                    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
                    std::unique_ptr<SharedProtoDatabaseProvider> db_provider);

  virtual ~ProtoDatabaseImpl() = default;

  void Init(Callbacks::InitStatusCallback callback) override;
  void Init(const leveldb_env::Options& unique_db_options,
            Callbacks::InitStatusCallback callback) override;

  // Internal only api.
  void InitWithDatabase(LevelDB* database,
                        const base::FilePath& database_dir,
                        const leveldb_env::Options& options,
                        Callbacks::InitStatusCallback callback);

  void UpdateEntries(std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
                         entries_to_save,
                     std::unique_ptr<KeyVector> keys_to_remove,
                     Callbacks::UpdateCallback callback) override;

  void UpdateEntriesWithRemoveFilter(
      std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector>
          entries_to_save,
      const KeyFilter& delete_key_filter,
      Callbacks::UpdateCallback callback) override;

  void LoadEntries(
      typename Callbacks::Internal<T>::LoadCallback callback) override;

  void LoadEntriesWithFilter(
      const KeyFilter& filter,
      typename Callbacks::Internal<T>::LoadCallback callback) override;
  void LoadEntriesWithFilter(
      const KeyFilter& key_filter,
      const leveldb::ReadOptions& options,
      const std::string& target_prefix,
      typename Callbacks::Internal<T>::LoadCallback callback) override;

  void LoadKeysAndEntries(
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
      override;

  void LoadKeysAndEntriesWithFilter(
      const KeyFilter& filter,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
      override;
  void LoadKeysAndEntriesWithFilter(
      const KeyFilter& filter,
      const leveldb::ReadOptions& options,
      const std::string& target_prefix,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
      override;
  void LoadKeysAndEntriesInRange(
      const std::string& start,
      const std::string& end,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
      override;
  void LoadKeysAndEntriesWhile(
      const std::string& start,
      const KeyIteratorController& controller,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
      override;

  void LoadKeys(Callbacks::LoadKeysCallback callback) override;

  void GetEntry(const std::string& key,
                typename Callbacks::Internal<T>::GetCallback callback) override;

  void Destroy(Callbacks::DestroyCallback callback) override;

  void RemoveKeysForTesting(const KeyFilter& key_filter,
                            const std::string& target_prefix,
                            Callbacks::UpdateCallback callback);

  // Not thread safe.
  ProtoDatabaseSelector* db_wrapper_for_testing() { return db_wrapper_.get(); }

 private:
  template <typename T_>
  friend class ProtoDatabaseImplTest;

  void InitInternal(const std::string& client_name,
                    const leveldb_env::Options& options,
                    bool use_shared_db,
                    Callbacks::InitStatusCallback callback);

  void PostTransaction(base::OnceClosure task);

  ProtoDbType db_type_;
  scoped_refptr<ProtoDatabaseSelector> db_wrapper_;
  const bool force_unique_db_;
  const scoped_refptr<base::SequencedTaskRunner> task_runner_;

  base::FilePath db_dir_;
};

namespace {

template <typename P,
          typename T,
          std::enable_if_t<std::is_base_of<google::protobuf::MessageLite,
                                           T>::value>* = nullptr>
std::string SerializeAsString(T* entry) {
  return entry->SerializeAsString();
}

template <typename P,
          typename T,
          std::enable_if_t<!std::is_base_of<google::protobuf::MessageLite,
                                            T>::value>* = nullptr>
std::string SerializeAsString(T* entry) {
  P proto;
  DataToProto(entry, &proto);
  return proto.SerializeAsString();
}

template <typename P>
bool ParseToProto(const std::string& serialized_entry, P* proto) {
  if (!proto->ParseFromString(serialized_entry)) {
    DLOG(WARNING) << "Unable to parse leveldb_proto entry";
    *proto = P();
    return false;
  }
  return true;
}

template <typename P,
          typename T,
          std::enable_if_t<std::is_base_of<google::protobuf::MessageLite,
                                           T>::value>* = nullptr>
bool ParseToClientType(const std::string& serialized_entry, T* output) {
  return ParseToProto<T>(serialized_entry, output);
}

template <typename P,
          typename T,
          std::enable_if_t<!std::is_base_of<google::protobuf::MessageLite,
                                            T>::value>* = nullptr>
bool ParseToClientType(const std::string& serialized_entry, T* entry) {
  P proto;
  if (!ParseToProto<P>(serialized_entry, &proto))
    return false;

  ProtoToData(&proto, entry);
  return true;
}

// Update transactions need to serialize the entries to be updated on background
// task runner. The database can be accessed on same task runner. The caller
// must wrap the callback using RunUpdateCallback() to ensure the callback runs
// in client task runner.
template <typename P, typename T>
void UpdateEntriesFromTaskRunner(
    std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
    std::unique_ptr<KeyVector> keys_to_remove,
    scoped_refptr<ProtoDatabaseSelector> db,
    Callbacks::UpdateCallback callback) {
  // Serialize the values from Proto to string before passing on to database.
  auto pairs_to_save = std::make_unique<KeyValueVector>();
  for (auto& pair : *entries_to_save) {
    auto serialized = SerializeAsString<P, T>(&pair.second);
    pairs_to_save->push_back(std::make_pair(pair.first, serialized));
  }

  db->UpdateEntries(std::move(pairs_to_save), std::move(keys_to_remove),
                    std::move(callback));
}

// Update transactions need to serialize the entries to be updated on background
// task runner. The database can be accessed on same task runner. The caller
// must wrap the callback using RunUpdateCallback() to ensure the callback runs
// in client task runner.
template <typename P, typename T>
void UpdateEntriesWithRemoveFilterFromTaskRunner(
    std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
    const KeyFilter& delete_key_filter,
    scoped_refptr<ProtoDatabaseSelector> db,
    Callbacks::UpdateCallback callback) {
  // Serialize the values from Proto to string before passing on to database.
  auto pairs_to_save = std::make_unique<KeyValueVector>();
  for (auto& pair : *entries_to_save) {
    auto serialized = SerializeAsString<P, T>(&pair.second);
    pairs_to_save->push_back(std::make_pair(pair.first, serialized));
  }

  db->UpdateEntriesWithRemoveFilter(std::move(pairs_to_save), delete_key_filter,
                                    std::move(callback));
}

// Load transactions happen on background task runner. The loaded entries need
// to be parsed into proto in background thread. This wraps the load callback
// and parses the entries and posts result onto client task runner.
template <typename P, typename T>
void ParseLoadedEntries(
    scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
    typename Callbacks::Internal<T>::LoadCallback callback,
    bool success,
    std::unique_ptr<ValueVector> loaded_entries) {
  auto entries = std::make_unique<std::vector<T>>();

  if (!success || !loaded_entries) {
    entries.reset();
  } else {
    for (const auto& serialized_entry : *loaded_entries) {
      entries->emplace_back(T());
      ParseToClientType<P, T>(serialized_entry, &entries->back());
    }
  }

  callback_task_runner->PostTask(
      FROM_HERE,
      base::BindOnce(std::move(callback), success, std::move(entries)));
}

// Load transactions happen on background task runner. The loaded entries need
// to be parsed into proto in background thread. This wraps the load callback
// and parses the entries and posts result onto client task runner.
template <typename P, typename T>
void ParseLoadedKeysAndEntries(
    scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
    typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback,
    bool success,
    std::unique_ptr<KeyValueMap> loaded_entries) {
  auto keys_entries = std::make_unique<std::map<std::string, T>>();
  if (!success || !loaded_entries) {
    keys_entries.reset();
  } else {
    for (const auto& pair : *loaded_entries) {
      auto it = keys_entries->emplace(pair.first, T());
      ParseToClientType<P, T>(pair.second, &(it.first->second));
    }
  }

  callback_task_runner->PostTask(
      FROM_HERE,
      base::BindOnce(std::move(callback), success, std::move(keys_entries)));
}

// Load transactions happen on background task runner. The loaded entries need
// to be parsed into proto in background thread. This wraps the load callback
// and parses the entries and posts result onto client task runner.
template <typename P, typename T>
void ParseLoadedEntry(
    scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
    typename Callbacks::Internal<T>::GetCallback callback,
    bool success,
    std::unique_ptr<std::string> serialized_entry) {
  auto entry = std::make_unique<T>();

  if (!success || !serialized_entry) {
    entry.reset();
  } else if (!ParseToClientType<P, T>(*serialized_entry, entry.get())) {
    success = false;
  }
  callback_task_runner->PostTask(
      FROM_HERE,
      base::BindOnce(std::move(callback), success, std::move(entry)));
}

}  // namespace

template <typename P, typename T>
ProtoDatabaseImpl<P, T>::ProtoDatabaseImpl(
    ProtoDbType db_type,
    const base::FilePath& db_dir,
    const scoped_refptr<base::SequencedTaskRunner>& task_runner)
    : db_type_(db_type),
      db_wrapper_(new ProtoDatabaseSelector(db_type_, task_runner, nullptr)),
      force_unique_db_(true),
      task_runner_(task_runner),
      db_dir_(db_dir) {}

template <typename P, typename T>
ProtoDatabaseImpl<P, T>::ProtoDatabaseImpl(
    ProtoDbType db_type,
    const base::FilePath& db_dir,
    const scoped_refptr<base::SequencedTaskRunner>& task_runner,
    std::unique_ptr<SharedProtoDatabaseProvider> db_provider)
    : db_type_(db_type),
      db_wrapper_(new ProtoDatabaseSelector(db_type_,
                                            task_runner,
                                            std::move(db_provider))),
      force_unique_db_(false),
      task_runner_(task_runner),
      db_dir_(db_dir) {}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::Init(
    typename Callbacks::InitStatusCallback callback) {
  bool use_shared_db =
      !force_unique_db_ &&
      SharedProtoDatabaseClientList::ShouldUseSharedDB(db_type_);
  const std::string& client_uma_name =
      SharedProtoDatabaseClientList::ProtoDbTypeToString(db_type_);

  InitInternal(client_uma_name, CreateSimpleOptions(), use_shared_db,
               std::move(callback));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::Init(
    const leveldb_env::Options& unique_db_options,
    typename Callbacks::InitStatusCallback callback) {
  bool use_shared_db =
      !force_unique_db_ &&
      SharedProtoDatabaseClientList::ShouldUseSharedDB(db_type_);
  const std::string& client_uma_name =
      SharedProtoDatabaseClientList::ProtoDbTypeToString(db_type_);

  InitInternal(client_uma_name, unique_db_options, use_shared_db,
               std::move(callback));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::InitInternal(
    const std::string& client_name,
    const leveldb_env::Options& unique_db_options,
    bool use_shared_db,
    Callbacks::InitStatusCallback callback) {
  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&ProtoDatabaseSelector::InitUniqueOrShared, db_wrapper_,
                     client_name, db_dir_, unique_db_options, use_shared_db,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::InitWithDatabase(
    LevelDB* database,
    const base::FilePath& database_dir,
    const leveldb_env::Options& options,
    Callbacks::InitStatusCallback callback) {
  DCHECK(force_unique_db_);
  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&ProtoDatabaseSelector::InitWithDatabase, db_wrapper_,
                     base::Unretained(database), database_dir, options,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::UpdateEntries(
    std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
    std::unique_ptr<KeyVector> keys_to_remove,
    Callbacks::UpdateCallback callback) {
  base::OnceClosure update_task = base::BindOnce(
      &UpdateEntriesFromTaskRunner<P, T>, std::move(entries_to_save),
      std::move(keys_to_remove), db_wrapper_,
      base::BindOnce(&RunUpdateCallback,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(update_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::UpdateEntriesWithRemoveFilter(
    std::unique_ptr<typename ProtoDatabase<T>::KeyEntryVector> entries_to_save,
    const KeyFilter& delete_key_filter,
    Callbacks::UpdateCallback callback) {
  base::OnceClosure update_task = base::BindOnce(
      &UpdateEntriesWithRemoveFilterFromTaskRunner<P, T>,
      std::move(entries_to_save), delete_key_filter, db_wrapper_,
      base::BindOnce(&RunUpdateCallback,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(update_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::LoadEntries(
    typename Callbacks::Internal<T>::LoadCallback callback) {
  LoadEntriesWithFilter(KeyFilter(), std::move(callback));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::LoadEntriesWithFilter(
    const KeyFilter& filter,
    typename Callbacks::Internal<T>::LoadCallback callback) {
  LoadEntriesWithFilter(filter, leveldb::ReadOptions(), std::string(),
                        std::move(callback));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::LoadEntriesWithFilter(
    const KeyFilter& key_filter,
    const leveldb::ReadOptions& options,
    const std::string& target_prefix,
    typename Callbacks::Internal<T>::LoadCallback callback) {
  base::OnceClosure load_task = base::BindOnce(
      &ProtoDatabaseSelector::LoadEntriesWithFilter, db_wrapper_, key_filter,
      options, target_prefix,
      base::BindOnce(&ParseLoadedEntries<P, T>,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(load_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::LoadKeysAndEntries(
    typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
  LoadKeysAndEntriesWithFilter(KeyFilter(), std::move(callback));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::LoadKeysAndEntriesWithFilter(
    const KeyFilter& filter,
    typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
  LoadKeysAndEntriesWithFilter(filter, leveldb::ReadOptions(), std::string(),
                               std::move(callback));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::LoadKeysAndEntriesWithFilter(
    const KeyFilter& filter,
    const leveldb::ReadOptions& options,
    const std::string& target_prefix,
    typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
  base::OnceClosure load_task = base::BindOnce(
      &ProtoDatabaseSelector::LoadKeysAndEntriesWithFilter, db_wrapper_, filter,
      options, target_prefix,
      base::BindOnce(&ParseLoadedKeysAndEntries<P, T>,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(load_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::LoadKeysAndEntriesInRange(
    const std::string& start,
    const std::string& end,
    typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
  base::OnceClosure load_task = base::BindOnce(
      &ProtoDatabaseSelector::LoadKeysAndEntriesInRange, db_wrapper_, start,
      end,
      base::BindOnce(&ParseLoadedKeysAndEntries<P, T>,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(load_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::LoadKeysAndEntriesWhile(
    const std::string& start,
    const KeyIteratorController& controller,
    typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
  base::OnceClosure load_task = base::BindOnce(
      &ProtoDatabaseSelector::LoadKeysAndEntriesWhile, db_wrapper_, start,
      controller,
      base::BindOnce(&ParseLoadedKeysAndEntries<P, T>,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(load_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::LoadKeys(Callbacks::LoadKeysCallback callback) {
  base::OnceClosure load_task = base::BindOnce(
      &ProtoDatabaseSelector::LoadKeys, db_wrapper_,
      base::BindOnce(&RunLoadKeysCallback,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(load_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::GetEntry(
    const std::string& key,
    typename Callbacks::Internal<T>::GetCallback callback) {
  base::OnceClosure get_task = base::BindOnce(
      &ProtoDatabaseSelector::GetEntry, db_wrapper_, key,
      base::BindOnce(&ParseLoadedEntry<P, T>,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(get_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::Destroy(Callbacks::DestroyCallback callback) {
  base::OnceClosure destroy_task = base::BindOnce(
      &ProtoDatabaseSelector::Destroy, db_wrapper_,
      base::BindOnce(&RunDestroyCallback,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(destroy_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::RemoveKeysForTesting(
    const KeyFilter& key_filter,
    const std::string& target_prefix,
    Callbacks::UpdateCallback callback) {
  base::OnceClosure update_task = base::BindOnce(
      &ProtoDatabaseSelector::RemoveKeysForTesting, db_wrapper_, key_filter,
      target_prefix,
      base::BindOnce(&RunUpdateCallback,
                     base::SequencedTaskRunner::GetCurrentDefault(),
                     std::move(callback)));
  PostTransaction(std::move(update_task));
}

template <typename P, typename T>
void ProtoDatabaseImpl<P, T>::PostTransaction(base::OnceClosure task) {
  task_runner_->PostTask(FROM_HERE,
                         base::BindOnce(&ProtoDatabaseSelector::AddTransaction,
                                        db_wrapper_, std::move(task)));
}

}  // namespace leveldb_proto

#endif  // COMPONENTS_LEVELDB_PROTO_INTERNAL_PROTO_DATABASE_IMPL_H_
