// Copyright 2018 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_LEVELDB_PROTO_UNIQUE_PROTO_DATABASE_H_
#define COMPONENTS_LEVELDB_PROTO_UNIQUE_PROTO_DATABASE_H_

#include "base/sequenced_task_runner.h"
#include "base/threading/thread_checker.h"
#include "components/leveldb_proto/leveldb_database.h"
#include "components/leveldb_proto/proto_database.h"
#include "components/leveldb_proto/proto_leveldb_wrapper.h"

namespace leveldb_proto {

// An implementation of ProtoDatabase<T> that manages the lifecycle of a unique
// LevelDB instance.
template <typename T>
class UniqueProtoDatabase : public ProtoDatabase<T> {
 public:
  explicit UniqueProtoDatabase(
      const scoped_refptr<base::SequencedTaskRunner>& task_runner);
  explicit UniqueProtoDatabase(std::unique_ptr<ProtoLevelDBWrapper>);
  virtual ~UniqueProtoDatabase();

  UniqueProtoDatabase(
      const base::FilePath& database_dir,
      const leveldb_env::Options& options,
      const scoped_refptr<base::SequencedTaskRunner>& task_runner);

  // This version of Init is for compatibility, since many of the current
  // proto database still use this.
  void Init(const char* client_name,
            const base::FilePath& database_dir,
            const leveldb_env::Options& options,
            typename Callbacks::InitCallback callback) override;

  void Init(const std::string& client_name,
            Callbacks::InitStatusCallback callback) override;

  void InitWithDatabase(LevelDB* database,
                        const base::FilePath& database_dir,
                        const leveldb_env::Options& options,
                        Callbacks::InitStatusCallback callback) override;

  void UpdateEntries(std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
                         entries_to_save,
                     std::unique_ptr<std::vector<std::string>> keys_to_remove,
                     Callbacks::UpdateCallback callback) override;

  void UpdateEntriesWithRemoveFilter(
      std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
          entries_to_save,
      const LevelDB::KeyFilter& delete_key_filter,
      Callbacks::UpdateCallback callback) override;
  void UpdateEntriesWithRemoveFilter(
      std::unique_ptr<typename Util::Internal<T>::KeyEntryVector>
          entries_to_save,
      const LevelDB::KeyFilter& delete_key_filter,
      const std::string& target_prefix,
      Callbacks::UpdateCallback callback) override;

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

  void LoadEntriesWithFilter(
      const LevelDB::KeyFilter& filter,
      typename Callbacks::Internal<T>::LoadCallback callback) override;
  void LoadEntriesWithFilter(
      const LevelDB::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 LevelDB::KeyFilter& filter,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
      override;
  void LoadKeysAndEntriesWithFilter(
      const LevelDB::KeyFilter& filter,
      const leveldb::ReadOptions& options,
      const std::string& target_prefix,
      typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback)
      override;

  void LoadKeys(Callbacks::LoadKeysCallback callback) override;
  void LoadKeys(const std::string& target_prefix,
                Callbacks::LoadKeysCallback callback) override;

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

  void Destroy(Callbacks::DestroyCallback callback) override;

  bool GetApproximateMemoryUse(uint64_t* approx_mem_use);

  // Sets the identifier used by the underlying LevelDB wrapper to record
  // metrics.
  void SetMetricsId(const std::string& id);

 protected:
  std::unique_ptr<ProtoLevelDBWrapper> db_wrapper_;
  scoped_refptr<base::SequencedTaskRunner> task_runner_;

 private:
  THREAD_CHECKER(thread_checker_);

  base::FilePath database_dir_;
  leveldb_env::Options options_;
  std::unique_ptr<LevelDB> db_;
};

template <typename T>
UniqueProtoDatabase<T>::UniqueProtoDatabase(
    const scoped_refptr<base::SequencedTaskRunner>& task_runner)
    : db_wrapper_(std::make_unique<ProtoLevelDBWrapper>(task_runner)) {}

template <typename T>
UniqueProtoDatabase<T>::UniqueProtoDatabase(
    std::unique_ptr<ProtoLevelDBWrapper> db_wrapper)
    : db_wrapper_(std::move(db_wrapper)) {}

template <typename T>
UniqueProtoDatabase<T>::UniqueProtoDatabase(
    const base::FilePath& database_dir,
    const leveldb_env::Options& options,
    const scoped_refptr<base::SequencedTaskRunner>& task_runner)
    : UniqueProtoDatabase<T>(task_runner) {
  database_dir_ = database_dir;
  options_ = options;
}

template <typename T>
UniqueProtoDatabase<T>::~UniqueProtoDatabase() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (db_.get() &&
      !db_wrapper_->task_runner()->DeleteSoon(FROM_HERE, db_.release())) {
    DLOG(WARNING) << "Proto database will not be deleted.";
  }
}

template <typename T>
void UniqueProtoDatabase<T>::Init(const std::string& client_name,
                                  Callbacks::InitStatusCallback callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  db_ = std::make_unique<LevelDB>(client_name.c_str());
  db_wrapper_->SetMetricsId(client_name);
  InitWithDatabase(db_.get(), database_dir_, options_, std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::Init(const char* client_name,
                                  const base::FilePath& database_dir,
                                  const leveldb_env::Options& options,
                                  Callbacks::InitCallback callback) {
  database_dir_ = database_dir;
  options_ = options;
  db_wrapper_->SetMetricsId(client_name);
  Init(std::string(client_name),
       base::BindOnce(
           [](Callbacks::InitCallback callback, Enums::InitStatus status) {
             std::move(callback).Run(status == Enums::InitStatus::kOK);
           },
           std::move(callback)));
}

template <typename T>
void UniqueProtoDatabase<T>::InitWithDatabase(
    LevelDB* database,
    const base::FilePath& database_dir,
    const leveldb_env::Options& options,
    Callbacks::InitStatusCallback callback) {
  // We set |destroy_on_corruption| to true to preserve the original behaviour
  // where database corruption led to automatic destruction.
  db_wrapper_->InitWithDatabase(database, database_dir, options,
                                true /* destroy_on_corruption */,
                                std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::UpdateEntries(
    std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
    std::unique_ptr<std::vector<std::string>> keys_to_remove,
    Callbacks::UpdateCallback callback) {
  db_wrapper_->template UpdateEntries<T>(std::move(entries_to_save),
                                         std::move(keys_to_remove),
                                         std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::UpdateEntriesWithRemoveFilter(
    std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
    const LevelDB::KeyFilter& delete_key_filter,
    Callbacks::UpdateCallback callback) {
  db_wrapper_->template UpdateEntriesWithRemoveFilter<T>(
      std::move(entries_to_save), delete_key_filter, std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::UpdateEntriesWithRemoveFilter(
    std::unique_ptr<typename Util::Internal<T>::KeyEntryVector> entries_to_save,
    const LevelDB::KeyFilter& delete_key_filter,
    const std::string& target_prefix,
    Callbacks::UpdateCallback callback) {
  db_wrapper_->template UpdateEntriesWithRemoveFilter<T>(
      std::move(entries_to_save), delete_key_filter, target_prefix,
      std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::LoadEntries(
    typename Callbacks::Internal<T>::LoadCallback callback) {
  db_wrapper_->template LoadEntries<T>(std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::LoadEntriesWithFilter(
    const LevelDB::KeyFilter& filter,
    typename Callbacks::Internal<T>::LoadCallback callback) {
  db_wrapper_->template LoadEntriesWithFilter<T>(filter, std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::LoadEntriesWithFilter(
    const LevelDB::KeyFilter& key_filter,
    const leveldb::ReadOptions& options,
    const std::string& target_prefix,
    typename Callbacks::Internal<T>::LoadCallback callback) {
  db_wrapper_->template LoadEntriesWithFilter<T>(
      key_filter, options, target_prefix, std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::LoadKeysAndEntries(
    typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
  db_wrapper_->template LoadKeysAndEntries<T>(std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::LoadKeysAndEntriesWithFilter(
    const LevelDB::KeyFilter& filter,
    typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
  db_wrapper_->template LoadKeysAndEntriesWithFilter<T>(filter,
                                                        std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::LoadKeysAndEntriesWithFilter(
    const LevelDB::KeyFilter& filter,
    const leveldb::ReadOptions& options,
    const std::string& target_prefix,
    typename Callbacks::Internal<T>::LoadKeysAndEntriesCallback callback) {
  db_wrapper_->template LoadKeysAndEntriesWithFilter<T>(
      filter, options, target_prefix, std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::LoadKeys(Callbacks::LoadKeysCallback callback) {
  db_wrapper_->LoadKeys(std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::LoadKeys(const std::string& target_prefix,
                                      Callbacks::LoadKeysCallback callback) {
  db_wrapper_->LoadKeys(target_prefix, std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::GetEntry(
    const std::string& key,
    typename Callbacks::Internal<T>::GetCallback callback) {
  db_wrapper_->template GetEntry<T>(key, std::move(callback));
}

template <typename T>
void UniqueProtoDatabase<T>::Destroy(Callbacks::DestroyCallback callback) {
  db_wrapper_->Destroy(std::move(callback));
}

template <typename T>
bool UniqueProtoDatabase<T>::GetApproximateMemoryUse(uint64_t* approx_mem_use) {
  return db_wrapper_->GetApproximateMemoryUse(approx_mem_use);
}

template <typename T>
void UniqueProtoDatabase<T>::SetMetricsId(const std::string& id) {
  db_wrapper_->SetMetricsId(id);
}

}  // namespace leveldb_proto

#endif  // COMPONENTS_LEVELDB_PROTO_UNIQUE_PROTO_DATABASE_H_
