// Copyright 2016 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_CONNECTION_H_
#define CONTENT_BROWSER_INDEXED_DB_INSTANCE_CONNECTION_H_

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

#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/types/expected.h"
#include "components/services/storage/privileged/mojom/indexed_db_client_state_checker.mojom.h"
#include "components/services/storage/public/cpp/buckets/bucket_info.h"
#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
#include "content/browser/indexed_db/instance/bucket_context_handle.h"
#include "content/browser/indexed_db/instance/database.h"
#include "content/browser/indexed_db/instance/transaction.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
#include "third_party/blink/public/common/indexeddb/indexeddb_key.h"
#include "third_party/blink/public/common/indexeddb/indexeddb_key_path.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"

namespace blink {
class IndexedDBKeyRange;
}

namespace content::indexed_db {

class DatabaseCallbacks;
class DatabaseError;
class BucketContext;

// This class maps to an IDB database *connection*:
// https://www.w3.org/TR/IndexedDB/#database-connection
//
// It has a 1:1 relationship with the Blink class IDBDatabase.
//
// It is created and operated on a bucket thread.
class CONTENT_EXPORT Connection : public blink::mojom::IDBDatabase {
 public:
  // Transfers ownership of an existing `connection` instance to a self owned
  // receiver. `Connection` instances begin life owned by a
  // `unique_ptr` in a pending state without any bound mojo remotes. IndexedDB
  // open database operations use this function to establish the connection
  // after the database is ready for use.
  static mojo::PendingAssociatedRemote<blink::mojom::IDBDatabase>
  MakeSelfOwnedReceiverAndBindRemote(std::unique_ptr<Connection> connection);

  Connection(BucketContext& bucket_context,
             base::WeakPtr<Database> database,
             base::RepeatingClosure on_version_change_ignored,
             base::OnceCallback<void(Connection&)> on_close,
             std::unique_ptr<DatabaseCallbacks> callbacks,
             mojo::Remote<storage::mojom::IndexedDBClientStateChecker>
                 client_state_checker,
             base::UnguessableToken client_token,
             int scheduling_priority);

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

  ~Connection() override;

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

  base::WeakPtr<Database> database() const { return database_; }
  DatabaseCallbacks* callbacks() const { return callbacks_.get(); }
  const base::UnguessableToken& client_token() const { return client_token_; }
  const std::map<int64_t, std::unique_ptr<Transaction>>& transactions() const {
    return transactions_;
  }

  // Unfortunately, for historical reasons, this version of `IsConnected()` is
  // not the same as whether `this` is connected via Mojo.
  bool IsConnected() const;

  // Since `this` is a self-owned mojo receiver (see
  // `MakeSelfOwnedReceiverAndBindRemote()`, this accessor is required to
  // determine whether the mojo connection is inactive, which is synonymous with
  // whether `this` is being destroyed.
  bool is_shutting_down() const { return is_shutting_down_; }
  int32_t id() const { return id_; }

  Transaction* CreateVersionChangeTransaction(
      int64_t id,
      const std::set<int64_t>& scope,
      std::unique_ptr<BackingStore::Transaction> backing_store_transaction);

  // Checks if the client is in inactive state and disallow it from activation
  // if so. This is called when the client is not supposed to be inactive,
  // otherwise it may affect the IndexedDB service (e.g. blocking others from
  // acquiring the locks).
  void DisallowInactiveClient(
      storage::mojom::DisallowInactiveClientReason reason,
      base::OnceCallback<void(bool)> callback);

  // We ignore calls where the id doesn't exist to facilitate the AbortAll call.
  // TODO(dmurph): Change that so this doesn't need to ignore unknown ids.
  void RemoveTransaction(int64_t id);

  void AbortTransactionAndTearDownOnError(Transaction* transaction,
                                          const DatabaseError& error);
  void CloseAndReportForceClose(const std::string& message);

  int scheduling_priority() const { return scheduling_priority_; }

  // Returns true if `this_one` should skip ahead of `other` when being added to
  // the lock manager/scheduler. Two lock requests (which can be associated with
  // transactions or new connection requests) will never be reordered if they
  // come from the same client (window/worker context).
  static bool HasHigherPriorityThan(const PartitionedLockHolder* this_one,
                                    const PartitionedLockHolder& other);

  // Returns true if any of the connection's transactions is holding one of the
  // lock IDs.
  bool IsHoldingLocks(const std::vector<PartitionedLockId>& lock_ids) const;

  // This should be called when handling a mojo message. It enforces that
  // internal state is reasonable, returning an error if not, in which case
  // the caller should abort handling the message, and pass the error back to
  // the frontend if appropriate.
  base::expected<Transaction*, DatabaseError> GetTransactionAndVerifyState(
      int64_t transaction_id,
      // When set, verifies that the transaction has this mode, killing the
      // renderer if not.
      std::optional<blink::mojom::IDBTransactionMode> required_mode = {});

 private:
  friend class TransactionTestBase;
  FRIEND_TEST_ALL_PREFIXES(DatabaseTest, ForcedClose);
  FRIEND_TEST_ALL_PREFIXES(DatabaseTest, PendingDelete);
  FRIEND_TEST_ALL_PREFIXES(DatabaseOperationTest, GetWithInvalidId);
  FRIEND_TEST_ALL_PREFIXES(TransactionTest, PostedStartTaskRunAfterAbort);

  // blink::mojom::IDBDatabase implementation
  void RenameObjectStore(int64_t transaction_id,
                         int64_t object_store_id,
                         const std::u16string& new_name) override;
  void CreateTransaction(
      mojo::PendingAssociatedReceiver<blink::mojom::IDBTransaction>
          transaction_receiver,
      int64_t transaction_id,
      const std::vector<int64_t>& object_store_ids,
      blink::mojom::IDBTransactionMode mode,
      blink::mojom::IDBTransactionDurability durability) override;
  void VersionChangeIgnored() override;
  void Get(int64_t transaction_id,
           int64_t object_store_id,
           int64_t index_id,
           blink::IndexedDBKeyRange key_range,
           bool key_only,
           blink::mojom::IDBDatabase::GetCallback callback) override;
  void GetAll(int64_t transaction_id,
              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) override;
  void OpenCursor(
      int64_t transaction_id,
      int64_t object_store_id,
      int64_t index_id,
      blink::IndexedDBKeyRange key_range,
      blink::mojom::IDBCursorDirection direction,
      bool key_only,
      blink::mojom::IDBTaskType task_type,
      blink::mojom::IDBDatabase::OpenCursorCallback callback) override;
  void Count(int64_t transaction_id,
             int64_t object_store_id,
             int64_t index_id,
             blink::IndexedDBKeyRange key_range,
             CountCallback callback) override;
  void DeleteRange(int64_t transaction_id,
                   int64_t object_store_id,
                   blink::IndexedDBKeyRange key_range,
                   DeleteRangeCallback success_callback) override;
  void GetKeyGeneratorCurrentNumber(
      int64_t transaction_id,
      int64_t object_store_id,
      GetKeyGeneratorCurrentNumberCallback callback) override;
  void Clear(int64_t transaction_id,
             int64_t object_store_id,
             ClearCallback callback) override;
  void CreateIndex(int64_t transaction_id,
                   int64_t object_store_id,
                   const blink::IndexedDBIndexMetadata& index) override;
  void DeleteIndex(int64_t transaction_id,
                   int64_t object_store_id,
                   int64_t index_id) override;
  void RenameIndex(int64_t transaction_id,
                   int64_t object_store_id,
                   int64_t index_id,
                   const std::u16string& new_name) override;
  void Abort(int64_t transaction_id) override;
  void DidBecomeInactive() override;
  void UpdatePriority(int new_priority) override;

  // It is an error to call either of these after `IsConnected()`
  // is no longer true.
  const storage::BucketInfo& GetBucketInfo();
  storage::BucketLocator GetBucketLocator();

  // Gets the transaction, returning null if it doesn't exist.
  Transaction* GetTransaction(int64_t id) const;

  enum class CloseErrorHandling {
    // Returns from the function on the first encounter with an error.
    kReturnOnFirstError,
    // Continues to call Abort() on all transactions despite any errors.
    // The last error encountered is returned.
    kAbortAllReturnLastError,
  };

  // The return value is `callbacks_`, passing ownership.
  std::unique_ptr<DatabaseCallbacks> AbortTransactionsAndClose(
      CloseErrorHandling error_handling,
      const std::string& message);

  // Returns the last error that occurred, if there is any.
  Status AbortAllTransactionsAndIgnoreErrors(const DatabaseError& error);

  Status AbortAllTransactions(const DatabaseError& error);

  BucketContext* bucket_context() {
    return bucket_context_handle_.bucket_context();
  }

  void RecordCreateTransactionHistograms(blink::mojom::IDBTransactionMode mode);

  const int32_t id_;

  // Keeps the factory for this bucket alive.
  BucketContextHandle bucket_context_handle_;

  base::WeakPtr<Database> database_;
  base::RepeatingClosure on_version_change_ignored_;
  base::OnceCallback<void(Connection&)> on_close_;

  // The connection owns transactions created on this connection. It's important
  // to preserve ordering.
  std::map<int64_t, std::unique_ptr<Transaction>> transactions_;

  // The callbacks_ member is cleared when the connection is closed.
  // May be nullptr in unit tests.
  std::unique_ptr<DatabaseCallbacks> callbacks_;

  mojo::Remote<storage::mojom::IndexedDBClientStateChecker>
      client_state_checker_;

  // TODO(381086791): Remove the per-reason split when the regression is fixed.
  static constexpr size_t kNumKeepActiveReasons =
      static_cast<size_t>(
          storage::mojom::DisallowInactiveClientReason::kMaxValue) +
      1;
  std::array<mojo::Remote<storage::mojom::IndexedDBClientKeepActive>,
             kNumKeepActiveReasons>
      client_keep_active_remotes_;

  // Uniquely identifies the document or worker that owns the other side of this
  // connection, i.e. the "client" of `client_state_checker_`. Since multiple
  // transactions/connections associated with a single client should never cause
  // that client to be ineligible for BFCache, this token is used to avoid
  // unnecessary calls to `DisallowInactiveClient()`.
  base::UnguessableToken client_token_;

  SEQUENCE_CHECKER(sequence_checker_);

  // The priority for transactions made on this connection. This corresponds to
  // the renderer's scheduler throttling state. See `HasHigherPriorityThan()`
  // for prioritization logic.
  int scheduling_priority_;

  bool is_shutting_down_ = false;

  // When connected, `this` is self-owned, but this reference to the self-owning
  // helper is necessary.
  mojo::SelfOwnedAssociatedReceiverRef<blink::mojom::IDBDatabase> receiver_;

  base::WeakPtrFactory<Connection> weak_factory_{this};
};

}  // namespace content::indexed_db

#endif  // CONTENT_BROWSER_INDEXED_DB_INSTANCE_CONNECTION_H_
