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

#ifndef NET_DISK_CACHE_SQL_SQL_BACKEND_IMPL_H_
#define NET_DISK_CACHE_SQL_SQL_BACKEND_IMPL_H_

#include <list>
#include <map>
#include <queue>
#include <set>
#include <variant>
#include <vector>

#include "base/byte_size.h"
#include "base/files/file_path.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ref.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "base/types/expected.h"
#include "base/types/strong_alias.h"
#include "net/base/net_errors.h"
#include "net/base/net_export.h"
#include "net/disk_cache/backend_cleanup_tracker.h"
#include "net/disk_cache/buildflags.h"
#include "net/disk_cache/disk_cache.h"
#include "net/disk_cache/sql/cache_entry_key.h"
#include "net/disk_cache/sql/entry_db_handle.h"
#include "net/disk_cache/sql/entry_write_buffer.h"
#include "net/disk_cache/sql/exclusive_operation_coordinator.h"
#include "net/disk_cache/sql/sql_async_task_manager.h"
#include "net/disk_cache/sql/sql_persistent_store.h"
#include "net/disk_cache/sql/sql_shared_cache_manager.h"
#include "net/disk_cache/sql/sql_write_buffer_memory_monitor.h"
#include "third_party/abseil-cpp/absl/container/flat_hash_map.h"

// This backend is experimental and only available when the build flag is set.
static_assert(BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND));

namespace base {
class SequencedTaskRunner;
}  // namespace base

namespace disk_cache {

class BackendCleanupTracker;
class SharedCacheClientRemote;
class SqlEntryImpl;

// Provides a concrete implementation of the disk cache backend that stores
// entries in a SQLite database. This class is responsible for all operations
// related to creating, opening, dooming, and enumerating cache entries.
//
// NOTE: This is currently a skeleton implementation, and some methods are not
// yet implemented, returning `net::ERR_NOT_IMPLEMENTED`.
class NET_EXPORT_PRIVATE SqlBackendImpl final : public Backend {
 public:
  // An enumeration of errors that can occur during the fake index file check.
  // These values are persisted to logs. Entries should not be renumbered and
  // numeric values should never be reused.
  //
  // LINT.IfChange(FakeIndexFileError)
  enum class FakeIndexFileError {
    kOkNew = 0,
    kOkExisting = 1,
    kCreateFileFailed = 2,
    kWriteFileFailed = 3,
    kWrongFileSize = 4,
    kOpenFileFailed = 5,
    kReadFileFailed = 6,
    kWrongMagicNumber = 7,
    kFailedToCreateDirectory = 8,
    kMaxValue = kFailedToCreateDirectory,
  };
  // LINT.ThenChange(//tools/metrics/histograms/metadata/net/enums.xml:SqlDiskCacheFakeIndexFileError)

  SqlBackendImpl(const base::FilePath& path,
                 int64_t max_bytes,
                 net::CacheType cache_type,
                 scoped_refptr<BackendCleanupTracker> cleanup_tracker);

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

  ~SqlBackendImpl() override;

  // Initializes the backend, which includes initializing the persistent store
  // and checking for a fake index file. These two operations are performed in
  // parallel.
  void Init(CompletionOnceCallback callback);

  // Backend interface.
  int64_t MaxFileSize() const override;
  base::expected<int32_t, net::Error> GetEntryCount(
      GetEntryCountCallback callback) const override;
  void SetMaxBytes(base::ByteSize max_bytes) override;
  base::ByteSize GetMaxBytesForTesting() const override;
  EntryResult OpenOrCreateEntry(const std::string& key,
                                net::RequestPriority priority,
                                EntryResultCallback callback) override;
  EntryResult OpenEntry(const std::string& key,
                        net::RequestPriority priority,
                        EntryResultCallback callback) override;
  EntryResult CreateEntry(const std::string& key,
                          net::RequestPriority priority,
                          EntryResultCallback callback) override;
  net::Error DoomEntry(const std::string& key,
                       net::RequestPriority priority,
                       CompletionOnceCallback callback) override;
  net::Error DoomAllEntries(CompletionOnceCallback callback) override;
  net::Error DoomEntriesBetween(base::Time initial_time,
                                base::Time end_time,
                                CompletionOnceCallback callback) override;
  net::Error DoomEntriesSince(base::Time initial_time,
                              CompletionOnceCallback callback) override;
  int64_t CalculateSizeOfAllEntries(
      Int64CompletionOnceCallback callback) override;
  int64_t CalculateSizeOfEntriesBetween(
      base::Time initial_time,
      base::Time end_time,
      Int64CompletionOnceCallback callback) override;
  std::unique_ptr<Iterator> CreateIterator() override;
  void GetStats(base::StringPairs* stats) override;
  void OnExternalCacheHit(const std::string& key) override;
  uint8_t GetEntryInMemoryData(const std::string& key) override;
  void OnBrowserIdle() override;

  bool SupportsSharedCache() const override;
  void RegisterSharedCacheClientRemote(
      const net::NetworkIsolationKey& network_isolation_key,
      std::unique_ptr<SharedCacheClientRemote> client) override;
  void OnEntryEligibleForSharedCache(
      const std::string& key,
      const GURL& url,
      std::unique_ptr<net::HttpResponseInfo> response_info,
      const net::NetworkIsolationKey& network_isolation_key) override;
  void ProcessAllSharedCacheEligibleEntriesForTest(
      base::ScopedClosureRunner scoped_closure_runner) override;

  // Called by SqlEntryImpl when it's being closed and is not doomed.
  // Removes the entry from `active_entries_`.
  void ReleaseActiveEntry(SqlEntryImpl& entry);
  // Called by SqlEntryImpl when it's being closed and is doomed.
  // Removes the entry from `doomed_entries_`.
  void ReleaseDoomedEntry(SqlEntryImpl& entry);

  // Marks an active entry as doomed and initiates its removal from the store.
  void DoomActiveEntry(SqlEntryImpl& entry);

  // Writes data and updates metadata (header and last_used) for an entry in a
  // single operation.
  void WriteEntryDataAndMetadata(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      std::optional<int64_t> old_body_end,
      int64_t body_end,
      EntryWriteBuffer buffer,
      base::Time last_used,
      const std::optional<MemoryEntryDataHints>& new_hints,
      scoped_refptr<net::GrowableIOBuffer> head_buffer,
      int64_t header_size_delta,
      CompletionOnceCallback callback);

  // Writes data to an entry's body (stream 1). This can be used to write new
  // data, overwrite existing data, or append to the entry. The operation is
  // scheduled via the `ExclusiveOperationCoordinator` to ensure proper
  // serialization.
  // If `db_handle` is in the initial state, creates entry information in the
  // DB. `last_used` is used only in that case.
  // If the backend is deleted during execution, the callback will be called
  // with net::ERR_ABORTED.
  int WriteEntryData(const CacheEntryKey& key,
                     const scoped_refptr<EntryDbHandle>& db_handle,
                     int64_t old_body_end,
                     int64_t body_end,
                     EntryWriteBuffer buffer,
                     bool truncate,
                     base::Time last_used,
                     bool sparse_write,
                     int64_t header_size,
                     bool copy_buffer_for_optimistic_write,
                     CompletionOnceCallback callback);

  // Reads data from an entry's body (stream 1). The operation is scheduled via
  // the `ExclusiveOperationCoordinator`. `sparse_reading` controls whether
  // gaps in the data are filled with zeros or cause the read to stop.
  // If the backend is deleted during execution, the callback will be called
  // with net::ERR_ABORTED.
  int ReadEntryData(const CacheEntryKey& key,
                    const scoped_refptr<EntryDbHandle>& db_handle,
                    int64_t offset,
                    scoped_refptr<net::IOBuffer> buffer,
                    int buf_len,
                    int64_t body_end,
                    bool sparse_reading,
                    SqlPersistentStore::ReadResultOrErrorCallback callback);

  // Copies data from Shared Cache to the main database blob table and then
  // executes the write operation for `buffer`. Scheduled as a normal operation
  // via `ExclusiveOperationCoordinator`.
  int CopySharedCacheToBlobTableAndWrite(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t offset,
      scoped_refptr<net::IOBuffer> buffer,
      int buf_len,
      int64_t old_body_end,
      bool truncate,
      base::Time last_used,
      bool sparse_write,
      size_t header_size,
      CompletionOnceCallback callback);

  // Finds the available contiguous range of data for a given entry. The
  // operation is scheduled via the `ExclusiveOperationCoordinator` to ensure
  // proper serialization.
  // If the backend is deleted during execution, the callback will be called
  // with net::ERR_ABORTED.
  RangeResult GetEntryAvailableRange(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t offset,
      int len,
      RangeResultCallback callback);

  // Sets the in-memory hints for the entry identified by `key` and
  // `db_handle`. This schedules an operation to update the in-memory
  // index.
  void SetEntryDataHints(const CacheEntryKey& key,
                         const scoped_refptr<EntryDbHandle>& db_handle,
                         MemoryEntryDataHints hints);

  // Returns the memory monitor for write buffers.
  SqlWriteBufferMemoryMonitor& write_buffer_monitor() {
    return write_buffer_monitor_;
  }

  // Runs the message loop until all tracked tasks are complete, for unit tests.
  void RunUntilAllTasksCompleteForTest();

  std::vector<scoped_refptr<base::SequencedTaskRunner>>&
  GetBackgroundTaskRunnersForTest() {
    return background_task_runners_;
  }

  SqlPersistentStore* GetSqlStoreForTest() { return store_.get(); }

  SqlAsyncTaskManager& async_task_manager() { return async_task_manager_; }

  SqlSharedCacheManager* GetSharedCacheManager() const {
    return store_ ? store_->GetSharedCacheManager() : nullptr;
  }

  // Enables a strict corruption checking mode for testing purposes. When
  // enabled, any detected database corruption will cause an immediate crash
  // via a `CHECK` failure. This is primarily useful for fuzzers, which can more
  // easily identify problematic inputs if the process fails fast, rather than
  // silently recovering.
  void EnableStrictCorruptionCheckForTesting();

  // Returns the current size of the `in_flight_entry_modifications_` map.
  // This is for testing purposes only.
  size_t GetSizeOfInFlightEntryModificationsMapForTesting() {
    return in_flight_entry_modifications_.size();
  }

  int64_t GetOptimisticWriteBufferTotalSizeForTesting() {
    return optimistic_write_buffer_monitor_.CurrentSize();
  }

  int64_t GetWriteBufferTotalSizeForTesting() {
    return write_buffer_monitor_.CurrentSize();
  }

  // Triggers a single pass of processing for currently eligible entries for
  // shared cache. If processing is interrupted or aborted by pending normal
  // operations, unprocessed entries are re-inserted into
  // `shared_cache_eligible_entries_`, and `scoped_closure_runner` runs when
  // this single pass completes (even if some entries remain unprocessed).
  void ProcessSharedCacheEligibleEntriesForTest(
      base::ScopedClosureRunner scoped_closure_runner,
      base::RepeatingCallback<void(const CacheEntryKey&)>
          on_entry_copied_callback);

  // Continuously triggers processing of eligible entries in a loop until
  // `shared_cache_eligible_entries_` becomes empty. Unlike
  // `ProcessSharedCacheEligibleEntriesForTest`, if any pass is interrupted or
  // aborted, remaining entries are automatically re-triggered for processing
  // until no eligible entries remain. `scoped_closure_runner` runs only after
  // all eligible entries have been processed.
  void ProcessAllSharedCacheEligibleEntriesWithCallbackForTest(
      base::ScopedClosureRunner scoped_closure_runner,
      base::RepeatingCallback<void(const CacheEntryKey&)>
          on_entry_copied_callback);

  size_t GetSharedCacheEligibleEntriesCountForTest() const override;

  const absl::flat_hash_map<CacheEntryKey,
                            SqlPersistentStore::SharedCacheEligibleEntry>&
  GetSharedCacheEligibleEntriesForTest() {
    return shared_cache_eligible_entries_;
  }

  ExclusiveOperationCoordinator* GetExclusiveOperationCoordinatorForTest() {
    return &exclusive_operation_coordinator_;
  }

  base::WeakPtr<SqlBackendImpl> GetWeakPtr();

 private:
  class IteratorImpl;

  // A RAII helper that ensures `PopInFlightEntryModification` is called when
  // it goes out of scope. This guarantees that an in-flight modification is
  // removed from `in_flight_entry_modifications_` once the associated operation
  // completes or is aborted.
  using PopInFlightEntryModificationRunner =
      base::StrongAlias<class PopInFlightEntryModificationRunnerTag,
                        base::ScopedClosureRunner>;

  // Identifies the type of a entry operation.
  enum class OpenOrCreateEntryOperationType {
    kCreateEntry,
    kOpenEntry,
    kOpenOrCreateEntry,
  };

  // Represents an in-flight modification to an entry's metadata (e.g.,
  // last_used, header). These modifications are queued and applied when the
  // entry is re-activated by `Iterator::OpenNextEntry()`.
  struct InFlightEntryModification {
    InFlightEntryModification(const scoped_refptr<EntryDbHandle>& db_handle,
                              base::Time last_used);
    InFlightEntryModification(const scoped_refptr<EntryDbHandle>& db_handle,
                              base::Time last_used,
                              scoped_refptr<net::GrowableIOBuffer> head);
    InFlightEntryModification(const scoped_refptr<EntryDbHandle>& db_handle,
                              base::Time last_used,
                              const std::optional<MemoryEntryDataHints>& hints,
                              scoped_refptr<net::GrowableIOBuffer> head,
                              int64_t body_end);
    InFlightEntryModification(const scoped_refptr<EntryDbHandle>& db_handle,
                              int64_t body_end);
    ~InFlightEntryModification();
    InFlightEntryModification(InFlightEntryModification&&);

    scoped_refptr<EntryDbHandle> db_handle;
    std::optional<base::Time> last_used;
    std::optional<MemoryEntryDataHints> hints;
    std::optional<scoped_refptr<net::GrowableIOBuffer>> head;
    std::optional<int64_t> body_end;
  };

  void OnInitialized(CompletionOnceCallback callback,
                     base::ElapsedTimer init_start_time,
                     const std::vector<bool>& results);
  void OnCheckFakeIndexFileFinished(CompletionOnceCallback callback,
                                    base::ElapsedTimer init_start_time,
                                    bool success);
  void OnStoreInitialized(CompletionOnceCallback callback,
                          base::ElapsedTimer init_start_time,
                          SqlPersistentStore::Error error);
  void RunDelayedPostInitializationTasks();

  SqlEntryImpl* GetActiveEntry(const CacheEntryKey& key);

  // Flushes the write buffers of all active entries.
  // This is primarily used to ensure that lazy entry creations and pending
  // writes are visible to subsequent asynchronous database operations.
  void FlushActiveEntriesBuffers() const;

  // Checks if the cache size has exceeded the high watermark and, if so,
  // schedules an eviction task. This is typically called after operations that
  // might increase the cache size. The eviction itself is run as an exclusive
  // operation to prevent conflicts with other cache activities.
  void MaybeTriggerEviction(bool is_idle_time_eviction);

  // Internal helper for Open/Create/OpenOrCreate operations. It uses
  // `ExclusiveOperationCoordinator` to serialize operations on the same key and
  // to correctly handle synchronous vs. asynchronous returns.
  EntryResult OpenOrCreateEntryInternal(OpenOrCreateEntryOperationType type,
                                        const std::string& key,
                                        EntryResultCallback callback);

  // Handles the backend logic for Open/Create/OpenOrCreate operations. This
  // method is scheduled as a normal operation via the
  // `ExclusiveOperationCoordinator` to ensure proper serialization against
  // other operations on the same key.
  void HandleOpenOrCreateEntryOperation(
      OpenOrCreateEntryOperationType type,
      const CacheEntryKey& entry_key,
      EntryResultCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Callback for store operations that return an EntryInfo (`OpenOrCreate()`,
  // `Create()`).
  void OnEntryOperationFinished(
      const CacheEntryKey& key,
      EntryResultCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle,
      SqlPersistentStore::EntryInfoOrError result);

  // Creates a new entry speculatively and returns it immediately. The actual
  // database insertion is performed in the background.
  EntryResult SpeculativeCreateEntry(
      const CacheEntryKey& entry_key,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for `DoomActiveEntry()`. This method is scheduled
  // as a normal operation via the `ExclusiveOperationCoordinator`.
  void HandleDoomActiveEntryOperation(
      scoped_refptr<SqlEntryImpl> entry,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Dooms an active entry. This method must be called while holding an
  // `ExclusiveOperationCoordinator::OperationHandle` to ensure proper
  // serialization of operations on the entry.
  void DoomActiveEntryInternal(SqlEntryImpl& entry,
                               CompletionOnceCallback callback);

  // Handles the backend logic for `ReleaseDoomedEntry()`. This method is
  // scheduled as a normal operation via the `ExclusiveOperationCoordinator`.
  void HandleDeleteDoomedEntry(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for `DoomEntry()`. This method is scheduled as a
  // normal operation via the `ExclusiveOperationCoordinator`.
  void HandleDoomEntryOperation(
      const CacheEntryKey& key,
      net::RequestPriority priority,
      CompletionOnceCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for `DoomEntriesBetween()`. This method is
  // scheduled as an exclusive operation via the
  // `ExclusiveOperationCoordinator`.
  void HandleDoomEntriesBetweenOperation(
      base::Time initial_time,
      base::Time end_time,
      CompletionOnceCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for `CalculateSizeOfEntriesBetween()`. This
  // method is scheduled as an exclusive operation via the
  // `ExclusiveOperationCoordinator`.
  void HandleCalculateSizeOfEntriesBetweenOperation(
      base::Time initial_time,
      base::Time end_time,
      Int64CompletionOnceCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for `WriteEntryDataAndMetadata()`. This method is
  // scheduled as a normal operation via the `ExclusiveOperationCoordinator`.
  void HandleWriteEntryDataAndMetadataOperation(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      std::optional<int64_t> old_body_end,
      EntryWriteBuffer buffer,
      base::Time last_used,
      const std::optional<MemoryEntryDataHints>& new_hints,
      scoped_refptr<net::GrowableIOBuffer> head_buffer,
      int64_t header_size_delta,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      SqlPersistentStore::ResIdOrErrorCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for a non-optimistic write operation. This method
  // is scheduled as a normal operation via the `ExclusiveOperationCoordinator`
  // and forwards the call to the persistent store.
  void HandleWriteEntryDataOperation(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t old_body_end,
      EntryWriteBuffer buffer,
      bool truncate,
      base::Time last_used,
      bool sparse_write,
      int64_t header_size,
      SqlPersistentStore::ResIdOrErrorCallback callback,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for an optimistic write operation. This method is
  // scheduled as a normal operation via the `ExclusiveOperationCoordinator` and
  // forwards the write to the persistent store.
  void HandleOptimisticWriteEntryDataOperation(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t old_body_end,
      EntryWriteBuffer buffer,
      bool truncate,
      base::Time last_used,
      bool sparse_write,
      int64_t header_size,
      SqlPersistentStore::ResIdOrErrorCallback callback,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Called when an optimistic write is finished.
  void OnOptimisticWriteFinished(
      const CacheEntryKey& key,
      std::optional<SqlPersistentStore::ResId> res_id,
      SqlPersistentStore::ResIdOrErrorCallback callback,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle,
      SqlPersistentStore::ResIdOrError result);

  // Handles the backend logic for `ReadEntryData()`. This method is scheduled
  // as a normal operation via the `ExclusiveOperationCoordinator` and forwards
  // the call to the persistent store.
  void HandleReadEntryDataOperation(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t offset,
      scoped_refptr<net::IOBuffer> buffer,
      int buf_len,
      int64_t body_end,
      bool sparse_reading,
      SqlPersistentStore::ReadResultOrErrorCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  void HandleCopySharedCacheToBlobTableOperation(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t offset,
      scoped_refptr<net::IOBuffer> buffer,
      int buf_len,
      int64_t old_body_end,
      bool truncate,
      base::Time last_used,
      bool sparse_write,
      size_t header_size,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      CompletionOnceCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  void DoCopySharedCacheToBlobTableStep(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t offset,
      scoped_refptr<net::IOBuffer> buffer,
      int buf_len,
      int64_t old_body_end,
      bool truncate,
      base::Time last_used,
      bool sparse_write,
      size_t header_size,
      int64_t copy_offset,
      scoped_refptr<net::IOBuffer> copy_buffer,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      CompletionOnceCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  void OnReadFromSharedCacheForCopy(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t offset,
      scoped_refptr<net::IOBuffer> buffer,
      int buf_len,
      int64_t old_body_end,
      bool truncate,
      base::Time last_used,
      bool sparse_write,
      size_t header_size,
      int64_t copy_offset,
      scoped_refptr<net::IOBuffer> copy_buffer,
      int bytes_to_read,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      CompletionOnceCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle,
      SqlPersistentStore::ReadResultOrError result);

  void OnWriteToBlobTableForCopy(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t offset,
      scoped_refptr<net::IOBuffer> buffer,
      int buf_len,
      int64_t old_body_end,
      bool truncate,
      base::Time last_used,
      bool sparse_write,
      size_t header_size,
      int64_t copy_offset,
      scoped_refptr<net::IOBuffer> copy_buffer,
      int bytes_written,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      CompletionOnceCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle,
      SqlPersistentStore::ResIdOrError result);

  // Handles the backend logic for `GetEntryAvailableRange()`. This method is
  // scheduled as a normal operation via the `ExclusiveOperationCoordinator`
  // and forwards the call to the persistent store.
  void HandleGetEntryAvailableRangeOperation(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      int64_t offset,
      int len,
      RangeResultCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the operation to set in-memory hints. This is called by the
  // `ExclusiveOperationCoordinator` to ensure that `db_handle` is
  // properly set (e.g., if the entry creation is still in progress).
  void HandleSetEntryDataHintsOperation(
      const CacheEntryKey& key,
      const scoped_refptr<EntryDbHandle>& db_handle,
      MemoryEntryDataHints hints,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for cache eviction. This method is scheduled as
  // an exclusive operation to ensure no other cache activities are running. It
  // gathers the keys of all active entries to prevent them from being evicted
  // and then delegates the actual eviction logic to the persistent store.
  void HandleTriggerEvictionOperation(
      bool is_idle_time_eviction,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for `OnExternalCacheHit()`. This method is
  // scheduled as a normal operation via the `ExclusiveOperationCoordinator`.
  void HandleOnExternalCacheHitOperation(
      const CacheEntryKey& key,
      base::Time now,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Adds an `InFlightEntryModification` to the queue for `entry_key` and
  // returns a `PopInFlightEntryModificationRunner`. The returned runner ensures
  // that the modification is removed from the queue when the runner goes out of
  // scope, guaranteeing proper cleanup even in error paths.
  PopInFlightEntryModificationRunner PushInFlightEntryModification(
      const CacheEntryKey& entry_key,
      InFlightEntryModification in_flight_entry_modification);

  // Removes the oldest `InFlightEntryModification` from the queue for
  // `entry_key`. This is called by `PopInFlightEntryModificationRunner` when
  // an operation completes or is aborted.
  void PopInFlightEntryModification(const CacheEntryKey& entry_key);

  // Applies in-flight modifications to an entry's info.
  void ApplyInFlightEntryModifications(
      const CacheEntryKey& key,
      SqlPersistentStore::EntryInfo& entry_info);

  void ProcessSharedCacheEligibleEntries(
      base::ScopedClosureRunner scoped_closure_runner,
      base::RepeatingCallback<void(const CacheEntryKey&)>
          on_entry_copied_callback);

  void HandleProcessSharedCacheEligibleEntries(
      base::ScopedClosureRunner scoped_closure_runner,
      base::RepeatingCallback<void(const CacheEntryKey&)>
          on_entry_copied_callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  void OnProcessSharedCacheEligibleEntriesComplete(
      base::ScopedClosureRunner scoped_closure_runner,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle,
      std::vector<SqlPersistentStore::SharedCacheEligibleEntry>
          unprocessed_entries);

  SqlAsyncTaskManager async_task_manager_;

  scoped_refptr<BackendCleanupTracker> cleanup_tracker_;

  const base::FilePath path_;

  // Task runners for background SQLite operations.
  std::vector<scoped_refptr<base::SequencedTaskRunner>>
      background_task_runners_;

  // The persistent store that manages the SQLite database.
  std::unique_ptr<SqlPersistentStore> store_;

  // Coordinates exclusive and normal operations to ensure that exclusive
  // operations have exclusive access. This must be declared before
  // `active_entries_` and `doomed_entries_` to ensure it is destroyed after
  // them. This is critical because `exclusive_operation_coordinator_` may hold
  // the last `scoped_refptr` to a `SqlEntryImpl`.
  ExclusiveOperationCoordinator exclusive_operation_coordinator_;

  // Map of cache keys to currently active (opened) entries.
  // `raw_ref` is used because the SqlEntryImpl objects are ref-counted and
  // their lifetime is managed by their ref_count. This map only holds
  // non-owning references to them.
  std::map<CacheEntryKey, raw_ref<SqlEntryImpl>> active_entries_;

  // Set of entries that have been marked as doomed but are still active
  // (i.e., have outstanding references).
  std::set<raw_ref<const SqlEntryImpl>> doomed_entries_;

  // Queue of in-flight entry modifications that need to be applied.
  // These are typically updates to `last_used` or header data that occur
  // while an entry is not actively open.
  std::map<CacheEntryKey, std::list<InFlightEntryModification>>
      in_flight_entry_modifications_;

  // A flag to prevent queuing multiple eviction operations. It is set to true
  // when an eviction operation is posted to the `ExclusiveOperationCoordinator`
  // and reset to false when the operation begins execution. This ensures that
  // even if `MaybeTriggerEviction()` is called multiple times while an eviction
  // task is pending, only one will be in the queue at any time.
  bool eviction_operation_queued_ = false;

  // Monitors and limits the memory usage for optimistic writes to stream 1.
  // Optimistic writes allow the backend to complete write operations
  // immediately by posting the operation to a background sequence and returning
  // the result synchronously, assuming success. This monitor ensures that the
  // total size of data pending in these operations does not exceed
  // `kSqlDiskCacheOptimisticWriteBufferSize`.
  SqlWriteBufferMemoryMonitor optimistic_write_buffer_monitor_;

  // Monitors and limits the total memory usage of write buffers across all
  // open entries. Entries buffer sequential writes to stream 1 up to
  // `kSqlDiskCacheMaxWriteBufferSizePerEntry` before flushing to the backend.
  // This monitor limits the aggregate size of these buffers to
  // `kSqlDiskCacheMaxWriteBufferTotalSize`. When a buffer is flushed, the
  // reservation is released. If the flush is handled as an optimistic write,
  // the reservation is effectively transferred to
  // `optimistic_write_buffer_monitor_`.
  SqlWriteBufferMemoryMonitor write_buffer_monitor_;

  // Cached value of `net::features::kSqlDiskCacheReduceUma`.
  const bool reduce_uma_;

  // Entries that are eligible for the shared cache and pending processing.
  // Entries are registered via `OnEntryEligibleForSharedCache` and processed
  // asynchronously during browser idle time or via explicit test calls.
  // Unprocessed entries (e.g., due to aborts from concurrent operations) are
  // re-inserted here for subsequent processing.
  absl::flat_hash_map<CacheEntryKey,
                      SqlPersistentStore::SharedCacheEligibleEntry>
      shared_cache_eligible_entries_;

  // Weak pointer factory for this class.
  base::WeakPtrFactory<SqlBackendImpl> weak_factory_{this};
};

}  // namespace disk_cache

#endif  // NET_DISK_CACHE_SQL_SQL_BACKEND_IMPL_H_
