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

#ifndef CONTENT_BROWSER_INDEXED_DB_INSTANCE_DATABASE_H_
#define CONTENT_BROWSER_INDEXED_DB_INSTANCE_DATABASE_H_

#include <stddef.h>
#include <stdint.h>

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

#include "base/containers/queue.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "components/services/storage/indexed_db/locks/partitioned_lock_manager.h"
#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
#include "content/browser/indexed_db/indexed_db_value.h"
#include "content/browser/indexed_db/instance/backing_store.h"
#include "content/browser/indexed_db/instance/connection_coordinator.h"
#include "content/browser/indexed_db/instance/factory_client.h"
#include "content/browser/indexed_db/instance/pending_connection.h"
#include "content/browser/indexed_db/list_set.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/common/indexeddb/indexeddb_key.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h"

namespace blink {
class IndexedDBKeyRange;
struct IndexedDBDatabaseMetadata;
}  // namespace blink

namespace content::indexed_db {
class BucketContext;
struct IndexedDBDataLossInfo;
class Connection;
class DatabaseCallbacks;
class Transaction;
enum class CursorType;

// This class maps to a single IDB database:
// https://www.w3.org/TR/IndexedDB/#database
//
// It is created and operated on a bucket thread.
class CONTENT_EXPORT Database {
 public:
  // Used to report irrecoverable backend errors. The second argument can be
  // null.
  using ErrorCallback = base::RepeatingCallback<void(Status, const char*)>;

  Database(uint32_t id_for_locks,
           const std::u16string& name,
           BucketContext& bucket_context);

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

  virtual ~Database();

  BackingStore* backing_store();
  BackingStore::Database* backing_store_db() { return backing_store_db_.get(); }
  PartitionedLockManager& lock_manager();

  const blink::IndexedDBDatabaseMetadata& metadata() const {
    return backing_store_db_->GetMetadata();
  }
  const std::u16string& name() const { return name_; }
  int64_t version() const;
  bool IsInitialized() const;

  // Called to permanently delete the database wrapped by `this`. Will call
  // `on_complete` and release `locks` when done. This may be called more than
  // once, in which case latter calls are a no-op, and `on_complete` will not be
  // called. Returns an error, or the latest version of the deleted database
  // if successful, or 0 if the database had already been deleted.
  StatusOr<int64_t> DeleteDatabase(std::vector<PartitionedLock> locks,
                                   base::OnceClosure on_complete);

  // Builds the set of lock requests for the given transaction `mode` and
  // `scope`. `scope` is used iff `mode` is not `VersionChange`.
  std::vector<PartitionedLockManager::PartitionedLockRequest>
  BuildLockRequestsForTransaction(blink::mojom::IDBTransactionMode mode,
                                  const std::set<int64_t>& scope) const;

  const list_set<Connection*>& connections() const { return connections_; }

  size_t GetNumTransactionsAcrossAllConnections() const;

  Status RunTasks();
  void RegisterAndScheduleTransaction(Transaction* transaction);

  // The database object (this object) must be kept alive for the duration of
  // this call. This means the caller should own an
  // BucketContextHandle while calling this methods.
  Status ForceCloseAndRunTasks(const std::string& message);

  void ScheduleOpenConnection(std::unique_ptr<PendingConnection> connection);

  void ScheduleDeleteDatabase(std::unique_ptr<FactoryClient> factory_client,
                              base::OnceClosure on_deletion_complete);

  // Number of connections that have progressed passed initial open call.
  size_t ConnectionCount() const { return connections_.size(); }

  bool IsAcceptingConnections() const { return !force_closing_; }

  // Number of active open/delete calls (running or blocked on other
  // connections).
  size_t ActiveOpenDeleteCount() const {
    return connection_coordinator_.ActiveOpenDeleteCount();
  }

  // Number of open/delete calls that are waiting their turn.
  size_t PendingOpenDeleteCount() const {
    return connection_coordinator_.PendingOpenDeleteCount();
  }

  Status VersionChangeOperation(int64_t version, Transaction* transaction);

  Status GetOperation(int64_t object_store_id,
                      int64_t index_id,
                      blink::IndexedDBKeyRange key_range,
                      indexed_db::CursorType cursor_type,
                      blink::mojom::IDBDatabase::GetCallback callback,
                      Transaction* transaction);

  struct OpenCursorOperationParams {
    OpenCursorOperationParams();

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

    ~OpenCursorOperationParams();
    int64_t object_store_id;
    int64_t index_id;
    blink::IndexedDBKeyRange key_range;
    blink::mojom::IDBCursorDirection direction;
    indexed_db::CursorType cursor_type;
    blink::mojom::IDBTaskType task_type;
    blink::mojom::IDBDatabase::OpenCursorCallback callback;
  };
  Status OpenCursorOperation(std::unique_ptr<OpenCursorOperationParams> params,
                             const storage::BucketLocator& bucket_locator,
                             Transaction* transaction);

  Status CountOperation(int64_t object_store_id,
                        int64_t index_id,
                        blink::IndexedDBKeyRange key_range,
                        blink::mojom::IDBDatabase::CountCallback callback,
                        Transaction* transaction);

  Status DeleteRangeOperation(
      int64_t object_store_id,
      blink::IndexedDBKeyRange key_range,
      blink::mojom::IDBDatabase::DeleteRangeCallback success_callback,
      Transaction* transaction);

  Status GetKeyGeneratorCurrentNumberOperation(
      int64_t object_store_id,
      blink::mojom::IDBDatabase::GetKeyGeneratorCurrentNumberCallback callback,
      Transaction* transaction);

  Status ClearOperation(int64_t object_store_id,
                        blink::mojom::IDBDatabase::ClearCallback callback,
                        Transaction* transaction);

  // Use this factory function for GetAll instead of creating the operation
  // directly.
  base::OnceCallback<Status(Transaction*)> CreateGetAllOperation(
      int64_t object_store_id,
      int64_t index_id,
      blink::IndexedDBKeyRange key_range,
      blink::mojom::IDBGetAllResultType result_type,
      int64_t max_count,
      blink::mojom::IDBCursorDirection direction,
      blink::mojom::IDBDatabase::GetAllCallback callback,
      Transaction* transaction);

  bool IsObjectStoreIdInMetadata(int64_t object_store_id) const;
  bool IsObjectStoreIdAndMaybeIndexIdInMetadata(int64_t object_store_id,
                                                int64_t index_id) const;

  // Returns metadata relevant to idb-internals.
  storage::mojom::IdbDatabaseMetadataPtr GetIdbInternalsMetadata() const;
  // Called when the data used to populate the struct in
  // `GetIdbInternalsMetadata` is changed in a significant way.
  void NotifyOfIdbInternalsRelevantChange();

  base::WeakPtr<Database> AsWeakPtr() { return weak_factory_.GetWeakPtr(); }

  void AddConnectionForTesting(Connection* connection) {
    if (connections_.empty()) {
      OpenInternal();
    }
    connections_.insert(connection);
  }

  bool CanBeDestroyed();

 protected:
  friend class Transaction;
  friend class ConnectionCoordinator::ConnectionRequest;
  friend class ConnectionCoordinator::OpenRequest;
  friend class ConnectionCoordinator::DeleteRequest;

 private:
  FRIEND_TEST_ALL_PREFIXES(DatabaseTest, OpenDeleteClear);
  FRIEND_TEST_ALL_PREFIXES(DatabaseOperationTest,
                           ObjectStoreGetAllKeysWithInvalidObjectStoreId);
  FRIEND_TEST_ALL_PREFIXES(DatabaseOperationTest,
                           IndexGetAllKeysWithInvalidIndexId);
  friend class DatabaseOperationTest;

  void CallUpgradeTransactionStartedForTesting(int64_t old_version);

  class ConnectionRequest;
  class OpenRequest;
  class DeleteRequest;

  Status OpenInternal();
  const IndexedDBDataLossInfo& GetDataLossInfo() const;

  // This class informs its result sink of an error if a `GetAllOperation` is
  // deleted without being run. This functionality mimics that of
  // AbortOnDestruct callbacks. `GetAll()` cannot easily be shoe-horned into the
  // abort-on-destruct callback templating.
  class CONTENT_EXPORT GetAllResultSinkWrapper {
   public:
    GetAllResultSinkWrapper(base::WeakPtr<Transaction> transaction,
                            blink::mojom::IDBDatabase::GetAllCallback callback);
    ~GetAllResultSinkWrapper();

    mojo::AssociatedRemote<blink::mojom::IDBDatabaseGetAllResultSink>& Get();

    // An override for unit tests to bind the associated receiver successfully
    // without a pre-existing endpoint entanglement.
    void UseDedicatedReceiverForTesting() {
      use_dedicated_receiver_for_testing_ = true;
    }

   private:
    base::WeakPtr<Transaction> transaction_;
    blink::mojom::IDBDatabase::GetAllCallback callback_;
    mojo::AssociatedRemote<blink::mojom::IDBDatabaseGetAllResultSink>
        result_sink_;
    bool use_dedicated_receiver_for_testing_ = false;
  };

  Status GetAllOperation(int64_t object_store_id,
                         int64_t index_id,
                         blink::IndexedDBKeyRange key_range,
                         blink::mojom::IDBGetAllResultType result_type,
                         int64_t max_count,
                         blink::mojom::IDBCursorDirection direction,
                         std::unique_ptr<GetAllResultSinkWrapper> result_sink,
                         Transaction* transaction);

  // If there is no active request, grab a new one from the pending queue and
  // start it. Afterwards, possibly release the database by calling
  // MaybeReleaseDatabase().
  void ProcessRequestQueueAndMaybeRelease();

  // If there are no connections, pending requests, or an active request, then
  // this function will call `destroy_me_`, which can destruct this object.
  void MaybeReleaseDatabase();

  std::unique_ptr<Connection> CreateConnection(
      std::unique_ptr<DatabaseCallbacks> database_callbacks,
      mojo::Remote<storage::mojom::IndexedDBClientStateChecker>
          client_state_checker,
      base::UnguessableToken client_token,
      int scheduling_priority);

  // Ack that one of the connections notified with a "versionchange" event did
  // not promptly close. Therefore a "blocked" event should be fired at the
  // pending connection.
  void VersionChangeIgnored();

  bool HasNoConnections() const;

  void SendVersionChangeToAllConnections(int64_t old_version,
                                         int64_t new_version);

  // This can only be called when the given connection is closed and no longer
  // has any transaction objects.
  void ConnectionClosed(Connection* connection);

  // In rare cases there are a very large number of queued
  // requests/transactions, so calculations related to blocking or blocked
  // clients can be expensive. See crbug.com/384476946. This method is used for
  // shortcutting such operations when there's only a single client. Also
  // returns true for zero clients.
  bool OnlyHasOneClient() const;

  // Find the transactions that block `current_transaction` from acquiring the
  // locks, and ensure that the clients with blocking transactions are active.
  void RequireBlockingTransactionClientsToBeActive(
      Transaction* current_transaction,
      std::vector<PartitionedLockManager::PartitionedLockRequest>&
          lock_requests);

  // Gets metadata for the given object store ID, asserting that the object
  // store exists.
  const blink::IndexedDBObjectStoreMetadata& GetObjectStoreMetadata(
      int64_t object_store_id) const;

  // This ID uniquely identifies this database within this process. It's not
  // persisted anywhere. Only used when the backing store is SQLite.
  uint32_t id_for_locks_;
  std::u16string name_;

  // The object that owns `this`.
  raw_ref<BucketContext> bucket_context_;

  list_set<Connection*> connections_;

  // True once `ForceCloseAndRunTasks()` is called.
  bool force_closing_ = false;

  ConnectionCoordinator connection_coordinator_;

  // Null until `OpenInternal()` is called successfully, as well as after the
  // database has been deleted via `DeleteDatabase()`.
  std::unique_ptr<BackingStore::Database> backing_store_db_;

  // `weak_factory_` is used for all callback uses.
  base::WeakPtrFactory<Database> weak_factory_{this};
};

}  // namespace content::indexed_db

#endif  // CONTENT_BROWSER_INDEXED_DB_INSTANCE_DATABASE_H_
