// 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/files/file_path.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/types/strong_alias.h"
#include "net/base/net_export.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/exclusive_operation_coordinator.h"
#include "net/disk_cache/sql/sql_persistent_store.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 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:
  // For a speculatively created entry, this holds `std::nullopt` initially, and
  // when the entry creation task is complete, it will hold either the `ResId`
  // on success or an `Error` on failure. Otherwise, it just holds a `ResId`.
  // Callbacks passed to `SqlBackendImpl::PostOrRunNormalOperation()` with the
  // entry key can expect this to be populated with either a `ResId` or an
  // `Error`.
  using ResIdOrErrorHolder = base::RefCountedData<std::optional<
      std::variant<SqlPersistentStore::ResId, SqlPersistentStore::Error>>>;

  // 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);

  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;
  int32_t GetEntryCount(
      net::Int32CompletionOnceCallback callback) 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;
  void OnBrowserIdle() 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);

  // Updates the `last_used` timestamp for an entry.
  void UpdateEntryLastUsed(
      const CacheEntryKey& key,
      const scoped_refptr<ResIdOrErrorHolder>& res_id_or_error,
      base::Time last_used);

  // Updates the header data and `last_used` timestamp for an entry.
  void UpdateEntryHeaderAndLastUsed(
      const CacheEntryKey& key,
      const scoped_refptr<ResIdOrErrorHolder>& res_id_or_error,
      base::Time last_used,
      scoped_refptr<net::GrowableIOBuffer> buffer,
      int64_t header_size_delta);

  // 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 the backend is deleted during execution, the callback will be called
  // with net::ERR_ABORTED.
  int WriteEntryData(const CacheEntryKey& key,
                     const scoped_refptr<ResIdOrErrorHolder>& res_id_or_error,
                     int64_t old_body_end,
                     int64_t body_end,
                     int64_t offset,
                     scoped_refptr<net::IOBuffer> buffer,
                     int buf_len,
                     bool truncate,
                     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<ResIdOrErrorHolder>& res_id_or_error,
                    int64_t offset,
                    scoped_refptr<net::IOBuffer> buffer,
                    int buf_len,
                    int64_t body_end,
                    bool sparse_reading,
                    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<ResIdOrErrorHolder>& res_id_or_error,
      int64_t offset,
      int len,
      RangeResultCallback callback);

  // Sends a dummy operation through the background task runner via the
  // operation coordinator, for unit tests.
  int FlushQueueForTest(CompletionOnceCallback callback);

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

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

  // 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_total_size_;
  }

 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<ResIdOrErrorHolder>& res_id_or_error,
        base::Time last_used);
    InFlightEntryModification(
        const scoped_refptr<ResIdOrErrorHolder>& res_id_or_error,
        base::Time last_used,
        scoped_refptr<net::GrowableIOBuffer> head);
    InFlightEntryModification(
        const scoped_refptr<ResIdOrErrorHolder>& res_id_or_error,
        int64_t body_end);
    ~InFlightEntryModification();
    InFlightEntryModification(InFlightEntryModification&&);

    scoped_refptr<ResIdOrErrorHolder> res_id_or_error;
    std::optional<base::Time> last_used;
    std::optional<scoped_refptr<net::GrowableIOBuffer>> head;
    std::optional<int64_t> body_end;
  };

  void OnInitialized(CompletionOnceCallback callback,
                     const std::vector<bool>& results);
  void RunDelayedPostInitializationTasks();

  SqlEntryImpl* GetActiveEntry(const CacheEntryKey& key);

  // 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);
  // Callback for store operations that return an optional<EntryInfo>
  // (`Open()`).
  void OnOptionalEntryOperationFinished(
      const CacheEntryKey& key,
      EntryResultCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle,
      SqlPersistentStore::OptionalEntryInfoOrError 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);

  // Called when the background database operation for a speculative entry
  // creation is finished.
  void OnSpeculativeCreateEntryFinished(
      const scoped_refptr<ResIdOrErrorHolder>& res_id_or_error,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle,
      SqlPersistentStore::EntryInfoOrError result);

  // 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<ResIdOrErrorHolder>& res_id_or_error,
      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 `UpdateEntryLastUsed()`. This method is
  // scheduled as a normal operation via the `ExclusiveOperationCoordinator`.
  void HandleUpdateEntryLastUsedOperation(
      const CacheEntryKey& key,
      const scoped_refptr<ResIdOrErrorHolder>& res_id_or_error,
      base::Time last_used,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Handles the backend logic for `UpdateEntryHeaderAndLastUsed()`. This method
  // is scheduled as a normal operation via the `ExclusiveOperationCoordinator`.
  void HandleUpdateEntryHeaderAndLastUsedOperation(
      const CacheEntryKey& key,
      const scoped_refptr<ResIdOrErrorHolder>& res_id_or_error,
      base::Time last_used,
      scoped_refptr<net::GrowableIOBuffer> buffer,
      int64_t header_size_delta,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      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<ResIdOrErrorHolder>& res_id_or_error,
      int64_t old_body_end,
      int64_t offset,
      scoped_refptr<net::IOBuffer> buffer,
      int buf_len,
      bool truncate,
      SqlPersistentStore::ErrorCallback 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<ResIdOrErrorHolder>& res_id_or_error,
      int64_t old_body_end,
      int64_t offset,
      scoped_refptr<net::IOBuffer> buffer,
      int buf_len,
      bool truncate,
      SqlPersistentStore::ErrorCallback maybe_update_res_id_or_error_callback,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // Called when an optimistic write is finished. `buf_len` is the memory usage
  // consumed for the optimistic write.
  void OnOptimisticWriteFinished(
      const CacheEntryKey& key,
      SqlPersistentStore::ResId res_id,
      int buf_len,
      SqlPersistentStore::ErrorCallback maybe_update_res_id_or_error_callback,
      PopInFlightEntryModificationRunner pop_in_flight_entry_modification,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle,
      SqlPersistentStore::Error 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<ResIdOrErrorHolder>& res_id_or_error,
      int64_t offset,
      scoped_refptr<net::IOBuffer> buffer,
      int buf_len,
      int64_t body_end,
      bool sparse_reading,
      SqlPersistentStore::IntOrErrorCallback callback,
      std::unique_ptr<ExclusiveOperationCoordinator::OperationHandle> handle);

  // 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<ResIdOrErrorHolder>& res_id_or_error,
      int64_t offset,
      int len,
      RangeResultCallback callback,
      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);

  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_;

  // 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_;

  // Coordinates exclusive and normal operations to ensure that exclusive
  // operations have exclusive access.
  ExclusiveOperationCoordinator exclusive_operation_coordinator_;

  // 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;

  // The memory usage consumed for optimistic writes. Optimistic writes are
  // performed as long as this value does not exceed
  // `kSqlDiskCacheOptimisticWriteBufferSize`.
  int64_t optimistic_write_buffer_total_size_ = 0;

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

}  // namespace disk_cache

#endif  // NET_DISK_CACHE_SQL_SQL_BACKEND_IMPL_H_
