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

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

#include <algorithm>
#include <cstdint>
#include <memory>
#include <set>
#include <sstream>
#include <tuple>
#include <vector>

#include "base/containers/span.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/system/sys_info.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/test/gmock_expected_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "components/services/storage/public/cpp/buckets/bucket_info.h"
#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
#include "components/services/storage/public/cpp/buckets/constants.h"
#include "components/services/storage/public/mojom/quota_client.mojom.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "sql/test/test_helpers.h"
#include "storage/browser/quota/quota_client_type.h"
#include "storage/browser/quota/quota_database.h"
#include "storage/browser/quota/quota_features.h"
#include "storage/browser/quota/quota_internals.mojom.h"
#include "storage/browser/quota/quota_manager_impl.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/quota/quota_override_handle.h"
#include "storage/browser/quota/storage_directory_util.h"
#include "storage/browser/test/mock_quota_client.h"
#include "storage/browser/test/mock_special_storage_policy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/mojom/buckets/bucket_manager_host.mojom-shared.h"
#include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h"
#include "url/gurl.h"

using ::blink::StorageKey;
using ::blink::mojom::QuotaStatusCode;

namespace storage {

namespace {

// Values in bytes.
const int64_t kAvailableSpaceForApp = 13377331U;
const int64_t kMustRemainAvailableForSystem = kAvailableSpaceForApp / 2;
const int64_t kDefaultPoolSize = 1000;
const int64_t kDefaultPerStorageKeyQuota = 200 * 1024 * 1024;

struct UsageAndQuotaResult {
  QuotaStatusCode status;
  int64_t usage;
  int64_t quota;
};

struct GlobalUsageResult {
  int64_t usage;
  int64_t unlimited_usage;
};

struct StorageCapacityResult {
  int64_t total_space;
  int64_t available_space;
};

struct ClientBucketData {
  const char* origin;
  std::string name;
  int64_t usage;
  int64_t quota = 0;
};

struct UsageWithBreakdown {
  int64_t usage;
  blink::mojom::UsageBreakdownPtr breakdown;
};

struct UsageAndQuotaWithBreakdown {
  QuotaStatusCode status;
  int64_t usage;
  int64_t quota;
  blink::mojom::UsageBreakdownPtr breakdown;
};

// Returns a deterministic value for the amount of available disk space.
int64_t GetAvailableDiskSpaceForTest() {
  return kAvailableSpaceForApp + kMustRemainAvailableForSystem;
}

QuotaAvailability GetVolumeInfoForTests(const base::FilePath& unused) {
  int64_t available = static_cast<uint64_t>(GetAvailableDiskSpaceForTest());
  int64_t total = available * 2;
  return QuotaAvailability(total, available);
}

StorageKey ToStorageKey(const std::string& url) {
  return StorageKey::CreateFromStringForTesting(url);
}

const storage::mojom::BucketTableEntry* FindBucketTableEntry(
    const std::vector<storage::mojom::BucketTableEntryPtr>& bucket_entries,
    BucketId& id) {
  auto it = std::ranges::find(bucket_entries, id.value(),
                              &storage::mojom::BucketTableEntry::bucket_id);
  if (it == bucket_entries.end()) {
    return nullptr;
  }
  return it->get();
}

MATCHER_P2(MatchesBucketTableEntry, storage_key, use_count, "") {
  return testing::ExplainMatchResult(storage_key, arg->storage_key,
                                     result_listener) &&
         testing::ExplainMatchResult(use_count, arg->use_count,
                                     result_listener);
}

}  // namespace

class QuotaManagerImplTest : public testing::Test {
 protected:
  using BucketTableEntries = QuotaManagerImpl::BucketTableEntries;

 public:
  QuotaManagerImplTest() : mock_time_counter_(0) {}

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

  void SetUp() override {
    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
    mock_special_storage_policy_ =
        base::MakeRefCounted<MockSpecialStoragePolicy>();
    ResetQuotaManagerImpl(false /* is_incognito */);
  }

  void TearDown() override {
    // Make sure the quota manager cleans up correctly.
    quota_manager_impl_ = nullptr;
    task_environment_.RunUntilIdle();
  }

 protected:
  void ResetQuotaManagerImpl(bool is_incognito) {
    quota_manager_impl_ = base::MakeRefCounted<QuotaManagerImpl>(
        is_incognito, data_dir_.GetPath(),
        base::SingleThreadTaskRunner::GetCurrentDefault().get(),
        mock_special_storage_policy_.get(), GetQuotaSettingsFunc());
    SetQuotaSettings(kDefaultPoolSize, kDefaultPerStorageKeyQuota,
                     is_incognito ? INT64_C(0) : kMustRemainAvailableForSystem);

    // Don't (automatically) start the eviction for testing.
    quota_manager_impl_->eviction_disabled_ = true;
    // Don't query the hard disk for remaining capacity.
    quota_manager_impl_->get_volume_info_fn_ = &GetVolumeInfoForTests;
    additional_callback_count_ = 0;
  }

  MockQuotaClient* CreateAndRegisterClient(
      QuotaClientType client_type,
      base::span<const UnmigratedStorageKeyData> unmigrated_data =
          base::span<const UnmigratedStorageKeyData>()) {
    auto mock_quota_client = std::make_unique<storage::MockQuotaClient>(
        quota_manager_impl_->proxy(), client_type, unmigrated_data);
    MockQuotaClient* mock_quota_client_ptr = mock_quota_client.get();

    mojo::PendingRemote<storage::mojom::QuotaClient> quota_client;
    mojo::MakeSelfOwnedReceiver(std::move(mock_quota_client),
                                quota_client.InitWithNewPipeAndPassReceiver());
    quota_manager_impl_->RegisterClient(std::move(quota_client), client_type);
    return mock_quota_client_ptr;
  }

  // Creates buckets in QuotaDatabase if they don't exist yet, and sets usage
  // to the `client`.
  void RegisterClientBucketData(
      MockQuotaClient* client,
      base::span<const ClientBucketData> mock_data,
      std::map<BucketLocator, int64_t>* buckets_data_out = nullptr) {
    std::map<BucketLocator, int64_t> buckets_data;
    for (const ClientBucketData& data : mock_data) {
      base::test::TestFuture<QuotaErrorOr<BucketInfo>> future;
      BucketInitParams params(ToStorageKey(data.origin), data.name);
      params.quota = data.quota;
      quota_manager_impl_->UpdateOrCreateBucket(params, future.GetCallback());
      ASSERT_OK_AND_ASSIGN(auto bucket, future.Take());
      buckets_data.insert(std::pair<BucketLocator, int64_t>(
          bucket.ToBucketLocator(), data.usage));
    }
    if (buckets_data_out) {
      *buckets_data_out = buckets_data;
    }
    client->AddBucketsData(buckets_data);
  }

  void OpenDatabase() { quota_manager_impl_->EnsureDatabaseOpened(); }

  QuotaErrorOr<BucketInfo> UpdateOrCreateBucket(
      const BucketInitParams& params) {
    base::test::TestFuture<QuotaErrorOr<BucketInfo>> future;
    quota_manager_impl_->UpdateOrCreateBucket(params, future.GetCallback());
    return future.Take();
  }

  QuotaErrorOr<BucketInfo> CreateBucketForTesting(
      const StorageKey& storage_key,
      const std::string& bucket_name) {
    base::test::TestFuture<QuotaErrorOr<BucketInfo>> future;
    quota_manager_impl_->CreateBucketForTesting(storage_key, bucket_name,
                                                future.GetCallback());
    return future.Take();
  }

  QuotaErrorOr<BucketInfo> GetBucket(const StorageKey& storage_key,
                                     const std::string& bucket_name) {
    base::test::TestFuture<QuotaErrorOr<BucketInfo>> future;
    quota_manager_impl_->GetBucketByNameUnsafe(storage_key, bucket_name,
                                               future.GetCallback());
    return future.Take();
  }

  QuotaErrorOr<BucketInfo> GetBucketById(const BucketId& bucket_id) {
    base::test::TestFuture<QuotaErrorOr<BucketInfo>> future;
    quota_manager_impl_->GetBucketById(bucket_id, future.GetCallback());
    return future.Take();
  }

  std::set<StorageKey> GetAllStorageKeys() {
    base::test::TestFuture<std::set<StorageKey>> future;
    quota_manager_impl_->GetAllStorageKeys(
        future.GetCallback<const std::set<StorageKey>&>());
    return future.Take();
  }

  QuotaErrorOr<std::set<BucketInfo>> GetAllBuckets() {
    base::test::TestFuture<QuotaErrorOr<std::set<BucketInfo>>> future;
    quota_manager_impl_->GetAllBuckets(future.GetCallback());
    return future.Take();
  }

  QuotaErrorOr<std::set<BucketInfo>> GetBucketsForHost(
      const std::string& host) {
    base::test::TestFuture<QuotaErrorOr<std::set<BucketInfo>>> future;
    quota_manager_impl_->GetBucketsForHost(host, future.GetCallback());
    return future.Take();
  }

  QuotaErrorOr<std::set<BucketInfo>> GetBucketsForStorageKey(
      const StorageKey& storage_key,
      bool delete_expired = false) {
    base::test::TestFuture<QuotaErrorOr<std::set<BucketInfo>>> future;
    quota_manager_impl_->GetBucketsForStorageKey(
        storage_key, future.GetCallback(), delete_expired);
    return future.Take();
  }

  UsageAndQuotaResult GetUsageAndQuotaForWebApps(
      const StorageKey& storage_key) {
    base::test::TestFuture<QuotaStatusCode, int64_t, int64_t> future;
    quota_manager_impl_->GetUsageAndQuotaForWebApps(storage_key,
                                                    future.GetCallback());
    return {future.Get<0>(), future.Get<1>(), future.Get<2>()};
  }

  UsageAndQuotaResult GetUsageAndQuotaForBucket(const BucketInfo& bucket_info) {
    base::test::TestFuture<QuotaStatusCode, int64_t, int64_t> future;
    quota_manager_impl_->GetBucketUsageAndReportedQuota(bucket_info.id,
                                                        future.GetCallback());
    return {future.Get<0>(), future.Get<1>(), future.Get<2>()};
  }

  UsageAndQuotaWithBreakdown GetUsageAndQuotaWithBreakdown(
      const StorageKey& storage_key) {
    base::test::TestFuture<QuotaStatusCode, int64_t, int64_t,
                           blink::mojom::UsageBreakdownPtr>
        future;
    quota_manager_impl_->GetUsageAndReportedQuotaWithBreakdown(
        storage_key, future.GetCallback());
    auto result = future.Take();
    return {std::get<0>(result), std::get<1>(result), std::get<2>(result),
            std::move(std::get<3>(result))};
  }

  UsageAndQuotaResult GetUsageAndQuotaForStorageClient(
      const StorageKey& storage_key) {
    base::test::TestFuture<QuotaStatusCode, int64_t, int64_t> future;
    quota_manager_impl_->GetUsageAndQuota(storage_key, future.GetCallback());
    return {future.Get<0>(), future.Get<1>(), future.Get<2>()};
  }

  bool CheckForSufficientSpace(const BucketLocator& bucket,
                               int64_t bytes_to_be_written) {
    base::test::TestFuture<QuotaErrorOr<int64_t>> future;
    quota_manager_impl_->GetBucketSpaceRemaining(bucket, future.GetCallback());
    auto result = future.Take();
    return result.has_value() && (result.value() >= bytes_to_be_written);
  }

  void SetQuotaSettings(int64_t pool_size,
                        int64_t per_storage_key_quota,
                        int64_t must_remain_available) {
    QuotaSettings settings;
    settings.pool_size = pool_size;
    settings.per_storage_key_quota = per_storage_key_quota;
    settings.session_only_per_storage_key_quota =
        (per_storage_key_quota > 0) ? (per_storage_key_quota - 1) : 0;
    settings.must_remain_available = must_remain_available;
    settings.refresh_interval = base::TimeDelta::Max();
    quota_manager_impl_->SetQuotaSettings(settings);
  }

  using GetVolumeInfoFn = QuotaAvailability (*)(const base::FilePath&);

  void SetGetVolumeInfoFn(GetVolumeInfoFn fn) {
    quota_manager_impl_->SetGetVolumeInfoFnForTesting(fn);
  }

  GlobalUsageResult GetGlobalUsage() {
    base::test::TestFuture<int64_t, int64_t> future;
    quota_manager_impl_->GetGlobalUsage(future.GetCallback());
    return {future.Get<0>(), future.Get<1>()};
  }

  UsageWithBreakdown GetStorageKeyUsageWithBreakdown(
      const blink::StorageKey& storage_key) {
    base::test::TestFuture<int64_t, blink::mojom::UsageBreakdownPtr> future;
    quota_manager_impl_->GetStorageKeyUsageWithBreakdown(storage_key,
                                                         future.GetCallback());
    auto result = future.Take();
    return {std::get<0>(result), std::move(std::get<1>(result))};
  }

  void RunAdditionalUsageAndQuotaTask(const StorageKey& storage_key) {
    quota_manager_impl_->GetUsageAndQuota(
        storage_key,
        base::BindOnce(&QuotaManagerImplTest::DidGetUsageAndQuotaAdditional,
                       weak_factory_.GetWeakPtr()));
  }

  int EvictBucketData(const BucketLocator& bucket) {
    base::test::TestFuture<int> future;
    quota_manager_impl_->EvictBucketData({bucket}, future.GetCallback());
    return future.Get();
  }

  QuotaStatusCode DeleteBucketData(const BucketLocator& bucket,
                                   QuotaClientTypes quota_client_types) {
    base::test::TestFuture<QuotaStatusCode> future;
    quota_manager_impl_->DeleteBucketData(bucket, std::move(quota_client_types),
                                          future.GetCallback());
    return future.Get();
  }

  QuotaStatusCode DeleteHostData(const std::string& host) {
    base::test::TestFuture<QuotaStatusCode> future;
    quota_manager_impl_->DeleteHostData(host, future.GetCallback());
    return future.Get();
  }

  QuotaStatusCode FindAndDeleteBucketData(const StorageKey& storage_key,
                                          const std::string& bucket_name) {
    base::test::TestFuture<QuotaStatusCode> future;
    quota_manager_impl_->FindAndDeleteBucketData(storage_key, bucket_name,
                                                 future.GetCallback());
    return future.Get();
  }

  StorageCapacityResult GetStorageCapacity() {
    base::test::TestFuture<int64_t, int64_t> future;
    quota_manager_impl_->GetStorageCapacity(future.GetCallback());
    return {future.Get<0>(), future.Get<1>()};
  }

  void GetEvictionRoundInfo() {
    quota_status_ = QuotaStatusCode::kUnknown;
    settings_ = QuotaSettings();
    available_space_ = -1;
    total_space_ = -1;
    usage_ = -1;
    quota_manager_impl_->GetEvictionRoundInfo(
        base::BindOnce(&QuotaManagerImplTest::DidGetEvictionRoundInfo,
                       weak_factory_.GetWeakPtr()));
  }

  void NotifyDefaultBucketAccessed(const StorageKey& storage_key,
                                   const base::Time& time) {
    auto bucket = BucketLocator::ForDefaultBucket(storage_key);
    quota_manager_impl_->NotifyBucketAccessed(bucket, time);
  }

  void NotifyDefaultBucketAccessed(const StorageKey& storage_key) {
    NotifyDefaultBucketAccessed(storage_key, IncrementMockTime());
  }

  void NotifyBucketAccessed(const BucketLocator& bucket) {
    quota_manager_impl_->NotifyBucketAccessed(bucket, IncrementMockTime());
  }

  void ModifyDefaultBucketAndNotify(MockQuotaClient* client,
                                    const StorageKey& storage_key,
                                    int delta) {
    auto bucket = BucketLocator::ForDefaultBucket(storage_key);
    client->ModifyBucketAndNotify(bucket, delta);
  }

  // Gets just one bucket for eviction.
  std::optional<BucketLocator> GetEvictionBucket() {
    base::test::TestFuture<const std::set<BucketLocator>&> future;
    quota_manager_impl_->GetEvictionBuckets(
        /*target_usage=*/1, future.GetCallback());

    std::set<BucketLocator> bucket = future.Take();
    if (1u == bucket.size()) {
      return *bucket.begin();
    }
    EXPECT_TRUE(bucket.empty());
    return std::nullopt;
  }

  std::set<BucketLocator> GetEvictionBuckets(int64_t target_usage) {
    base::test::TestFuture<const std::set<BucketLocator>&> future;
    quota_manager_impl_->GetEvictionBuckets(target_usage, future.GetCallback());
    return future.Take();
  }

  std::set<BucketLocator> GetBucketsModifiedBetween(base::Time begin,
                                                    base::Time end) {
    base::test::TestFuture<std::set<BucketLocator>> future;
    quota_manager_impl_->GetBucketsModifiedBetween(
        begin, end, future.GetCallback<const std::set<BucketLocator>&>());
    return future.Get<0>();
  }

  BucketTableEntries DumpBucketTable() {
    base::test::TestFuture<BucketTableEntries> future;
    quota_manager_impl_->DumpBucketTable(future.GetCallback());
    return future.Take();
  }

  std::vector<storage::mojom::BucketTableEntryPtr> RetrieveBucketsTable() {
    base::test::TestFuture<std::vector<storage::mojom::BucketTableEntryPtr>>
        future;
    quota_manager_impl_->RetrieveBucketsTable(future.GetCallback());
    return future.Take();
  }

  void DidGetEvictionRoundInfo(QuotaStatusCode status,
                               const QuotaSettings& settings,
                               int64_t available_space,
                               int64_t total_space,
                               int64_t global_usage,
                               bool global_usage_is_complete) {
    quota_status_ = status;
    settings_ = settings;
    available_space_ = available_space;
    total_space_ = total_space;
    usage_ = global_usage;
  }

  void SetStoragePressureCallback(
      base::RepeatingCallback<void(const StorageKey&)> callback) {
    quota_manager_impl_->SetStoragePressureCallback(callback);
  }

  void MaybeRunStoragePressureCallback(const StorageKey& storage_key,
                                       int64_t total,
                                       int64_t available) {
    quota_manager_impl_->MaybeRunStoragePressureCallback(storage_key, total,
                                                         available);
  }

  void set_additional_callback_count(int c) { additional_callback_count_ = c; }
  int additional_callback_count() const { return additional_callback_count_; }
  void DidGetUsageAndQuotaAdditional(QuotaStatusCode status,
                                     int64_t usage,
                                     int64_t quota) {
    ++additional_callback_count_;
  }

  QuotaManagerImpl* quota_manager_impl() const {
    return quota_manager_impl_.get();
  }

  void set_quota_manager_impl(QuotaManagerImpl* quota_manager_impl) {
    quota_manager_impl_ = quota_manager_impl;
  }

  MockSpecialStoragePolicy* mock_special_storage_policy() const {
    return mock_special_storage_policy_.get();
  }

  std::unique_ptr<QuotaOverrideHandle> GetQuotaOverrideHandle() {
    return quota_manager_impl_->proxy()->GetQuotaOverrideHandle();
  }

  void SetQuotaChangeCallback(base::RepeatingClosure cb) {
    quota_manager_impl_->SetQuotaChangeCallbackForTesting(std::move(cb));
  }

  QuotaError CorruptDatabaseForTesting(
      base::OnceCallback<void(const base::FilePath&)> corrupter) {
    base::test::TestFuture<QuotaError> corruption_future;
    quota_manager_impl_->CorruptDatabaseForTesting(
        std::move(corrupter), corruption_future.GetCallback());
    return corruption_future.Get();
  }

  bool is_db_bootstrapping() {
    return quota_manager_impl_->is_bootstrapping_database_for_testing();
  }

  bool is_db_disabled() {
    return quota_manager_impl_->is_db_disabled_for_testing();
  }

  void DisableQuotaDatabase() {
    base::RunLoop run_loop;
    quota_manager_impl_->PostTaskAndReplyWithResultForDBThread(
        base::BindLambdaForTesting([&](QuotaDatabase* db) {
          db->SetDisabledForTesting(true);
          return QuotaError::kNone;
        }),
        base::BindLambdaForTesting([&](QuotaError error) { run_loop.Quit(); }),
        FROM_HERE, /*is_bootstrap_task=*/false);
    run_loop.Run();
  }

  void disable_database_bootstrap(bool disable) {
    quota_manager_impl_->SetBootstrapDisabledForTesting(disable);
  }

  QuotaStatusCode status() const { return quota_status_; }
  int64_t usage() const { return usage_; }
  int64_t quota() const { return quota_; }
  int64_t total_space() const { return total_space_; }
  int64_t available_space() const { return available_space_; }
  const QuotaSettings& settings() const { return settings_; }

  void SetupQuotaManagerObserver() {
    quota_manager_observer_run_loop_ = std::make_unique<base::RunLoop>();
    quota_manager_observer_test_ =
        std::make_unique<QuotaManagerObserverTest>(weak_factory_.GetWeakPtr());
  }

  void RunUntilObserverNotifies() {
    quota_manager_observer_run_loop_->Run();
    quota_manager_observer_run_loop_ = std::make_unique<base::RunLoop>();
  }

 protected:
  enum ObserverNotifyType {
    kCreateOrUpdate,
    kDelete,
  };
  struct ObserverNotification {
    explicit ObserverNotification(BucketInfo bucket)
        : type(ObserverNotifyType::kCreateOrUpdate), bucket_info(bucket) {}
    explicit ObserverNotification(BucketLocator locator)
        : type(ObserverNotifyType::kDelete), bucket_locator(locator) {}
    ObserverNotifyType type;
    std::optional<BucketInfo> bucket_info;
    std::optional<BucketLocator> bucket_locator;
  };

  base::test::ScopedFeatureList scoped_feature_list_;
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  base::ScopedTempDir data_dir_;
  scoped_refptr<QuotaManagerImpl> quota_manager_impl_;
  std::vector<ObserverNotification> observer_notifications_;

 private:
  class QuotaManagerObserverTest : storage::mojom::QuotaManagerObserver {
   public:
    explicit QuotaManagerObserverTest(base::WeakPtr<QuotaManagerImplTest> owner)
        : owner_(owner) {
      owner_->quota_manager_impl_->AddObserver(
          receiver_.BindNewPipeAndPassRemote());
    }

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

    ~QuotaManagerObserverTest() override = default;

    void OnCreateOrUpdateBucket(
        const storage::BucketInfo& bucket_info) override {
      owner_->observer_notifications_.emplace_back(bucket_info);
      QuitRunLoop();
    }

    void OnDeleteBucket(const storage::BucketLocator& bucket_locator) override {
      owner_->observer_notifications_.emplace_back(bucket_locator);
      QuitRunLoop();
    }

   private:
    void QuitRunLoop() {
      if (owner_->quota_manager_observer_run_loop_) {
        owner_->quota_manager_observer_run_loop_->Quit();
      }
    }
    base::WeakPtr<QuotaManagerImplTest> owner_;
    mojo::Receiver<storage::mojom::QuotaManagerObserver> receiver_{this};
  };

  base::Time IncrementMockTime() {
    ++mock_time_counter_;
    return base::Time::FromSecondsSinceUnixEpoch(mock_time_counter_ * 10.0);
  }

  scoped_refptr<MockSpecialStoragePolicy> mock_special_storage_policy_;

  QuotaStatusCode quota_status_;
  int64_t usage_;
  int64_t quota_;
  int64_t total_space_;
  int64_t available_space_;
  QuotaSettings settings_;
  std::unique_ptr<QuotaManagerObserverTest> quota_manager_observer_test_;
  std::unique_ptr<base::RunLoop> quota_manager_observer_run_loop_;

  int additional_callback_count_;

  int mock_time_counter_;

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

TEST_F(QuotaManagerImplTest, QuotaDatabaseBootstrap) {
  quota_manager_impl_->eviction_disabled_ = false;

  static const UnmigratedStorageKeyData kData1[] = {
      {"http://foo.com/", 10},
      {"http://foo.com:8080/", 15},
  };
  static const UnmigratedStorageKeyData kData2[] = {
      {"https://foo.com/", 30},
      {"https://foo.com:8081/", 35},
  };
  CreateAndRegisterClient(QuotaClientType::kFileSystem, kData1);
  CreateAndRegisterClient(QuotaClientType::kIndexedDatabase, kData2);

  // OpenDatabase should trigger database bootstrapping.
  OpenDatabase();
  EXPECT_TRUE(is_db_bootstrapping());

  // When bootstrapping is complete, queued calls to the QuotaDatabase
  // should return successfully and buckets for registered storage keys should
  // already exist.
  ASSERT_TRUE(GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName)
                  .has_value());
  EXPECT_FALSE(is_db_bootstrapping());

  ASSERT_TRUE(
      GetBucket(ToStorageKey("http://foo.com:8080/"), kDefaultBucketName)
          .has_value());

  ASSERT_TRUE(
      GetBucket(ToStorageKey("https://foo.com:8081/"), kDefaultBucketName)
          .has_value());

  // The first eviction round is initiated a few minutes after bootstrapping.
  EXPECT_FALSE(quota_manager_impl_->temporary_storage_evictor_);
  task_environment_.FastForwardBy(base::Minutes(10));
  EXPECT_TRUE(quota_manager_impl_->temporary_storage_evictor_);
}

TEST_F(QuotaManagerImplTest, CorruptionRecovery) {
  // Setup clients with both unmigrated and migrated data. Before corruption the
  // bucket data will be used, while after corruption recovery data should be
  // migrated again.
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 10},
      {"http://foo.com:8080/", kDefaultBucketName, 15},
  };
  static const UnmigratedStorageKeyData kUnmigratedData1[] = {
      {"http://foo.com/", 10},
      {"http://foo.com:8080/", 15},
  };
  static const ClientBucketData kData2[] = {
      {"https://foo.com/", kDefaultBucketName, 30},
      {"https://foo.com:8081/", kDefaultBucketName, 35},
  };
  static const UnmigratedStorageKeyData kUnmigratedData2[] = {
      {"https://foo.com/", 30},
      {"https://foo.com:8081/", 35},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem, kUnmigratedData1);
  MockQuotaClient* idb_client = CreateAndRegisterClient(
      QuotaClientType::kIndexedDatabase, kUnmigratedData2);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(idb_client, kData2);

  // Basic sanity checks, make sure setup worked correctly.
  ASSERT_TRUE(GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName)
                  .has_value());
  ASSERT_TRUE(
      GetBucket(ToStorageKey("http://foo.com:8080/"), kDefaultBucketName)
          .has_value());
  ASSERT_TRUE(
      GetBucket(ToStorageKey("https://foo.com:8081/"), kDefaultBucketName)
          .has_value());

  // Corrupt the database to make bucket lookup fail.
  QuotaError corruption_error = CorruptDatabaseForTesting(
      base::BindOnce([](const base::FilePath& db_path) {
        ASSERT_TRUE(
            sql::test::CorruptIndexRootPage(db_path, "buckets_by_storage_key"));
      }));
  ASSERT_EQ(QuotaError::kNone, corruption_error);

  // Try to lookup a bucket, this should report a failure.
  EXPECT_FALSE(quota_manager_impl_->is_db_disabled_for_testing());
  EXPECT_FALSE(is_db_bootstrapping());

  EXPECT_THAT(GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName),
              base::test::ErrorIs(QuotaError::kDatabaseError));

  // The last lookup attempt should have started another bootstrap attempt.
  EXPECT_TRUE(is_db_bootstrapping());

  // And with that bucket lookup should be working again.
  ASSERT_TRUE(GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName)
                  .has_value());
}

TEST_F(QuotaManagerImplTest, GetUsageInfo) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 10},
      {"http://foo.com:8080/", kDefaultBucketName, 15},
      {"http://bar.com/", "logs", 20},
  };
  static const ClientBucketData kData2[] = {
      {"https://foo.com/", kDefaultBucketName, 30},
      {"https://foo.com:8081/", kDefaultBucketName, 35},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(idb_client, kData2);

  base::test::TestFuture<UsageInfoEntries> future;
  quota_manager_impl()->GetUsageInfo(future.GetCallback());
  auto entries = future.Get();

  EXPECT_THAT(entries, testing::UnorderedElementsAre(
                           UsageInfo("foo.com", 10 + 15 + 30 + 35),
                           UsageInfo("bar.com", 20)));
}

TEST_F(QuotaManagerImplTest, UpdateUsageInfo) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 10},
      {"http://bar.com/", kDefaultBucketName, 50},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  std::map<BucketLocator, int64_t> buckets_data;
  RegisterClientBucketData(fs_client, kData1, &buckets_data);
  ASSERT_EQ(buckets_data.size(), 2u);
  BucketLocator first_bucket_locator = buckets_data.begin()->first;

  {
    base::test::TestFuture<UsageInfoEntries> future;
    quota_manager_impl()->GetUsageInfo(future.GetCallback());
    auto entries = future.Get();

    EXPECT_THAT(entries,
                testing::UnorderedElementsAre(UsageInfo("foo.com", 10),
                                              UsageInfo("bar.com", 50)));

    // The quota client was queried once for each bucket.
    EXPECT_EQ(2U, fs_client->get_bucket_usage_call_count());
  }

  // Notify of a change with a provided byte delta.
  quota_manager_impl()->NotifyBucketModified(
      QuotaClientType::kFileSystem, first_bucket_locator, /*delta=*/7,
      base::Time::Now(), base::DoNothing());

  {
    base::test::TestFuture<UsageInfoEntries> future;
    quota_manager_impl()->GetUsageInfo(future.GetCallback());
    auto entries = future.Get();

    EXPECT_THAT(entries,
                testing::UnorderedElementsAre(UsageInfo("foo.com", 17),
                                              UsageInfo("bar.com", 50)));

    // The quota client was not queried any more times since the values were
    // cached and then updated.
    EXPECT_EQ(2U, fs_client->get_bucket_usage_call_count());
  }

  // Dirty the cache by passing a null delta.
  quota_manager_impl()->NotifyBucketModified(
      QuotaClientType::kFileSystem, first_bucket_locator,
      /*delta=*/std::nullopt, base::Time::Now(), base::DoNothing());

  {
    base::test::TestFuture<UsageInfoEntries> future;
    quota_manager_impl()->GetUsageInfo(future.GetCallback());
    auto entries = future.Get();

    // Since the cache was tossed out, the mock quota client is consulted again
    // for its usage.
    EXPECT_THAT(entries,
                testing::UnorderedElementsAre(UsageInfo("foo.com", 10),
                                              UsageInfo("bar.com", 50)));

    // The quota client was queried one more time.
    EXPECT_EQ(3U, fs_client->get_bucket_usage_call_count());
  }
}

TEST_F(QuotaManagerImplTest, UpdateOrCreateBucket) {
  StorageKey storage_key = ToStorageKey("http://a.com/");
  std::string bucket_name = "bucket_a";

  ASSERT_OK_AND_ASSIGN(auto bucket,
                       UpdateOrCreateBucket({storage_key, bucket_name}));

  BucketId created_bucket_id = bucket.id;

  EXPECT_THAT(UpdateOrCreateBucket({storage_key, bucket_name}),
              base::test::ValueIs(
                  ::testing::Field(&BucketInfo::id, created_bucket_id)));
}

TEST_F(QuotaManagerImplTest, UpdateOrCreateBucket_Expiration) {
  auto clock = std::make_unique<base::SimpleTestClock>();
  QuotaDatabase::SetClockForTesting(clock.get());
  clock->SetNow(base::Time::Now());

  BucketInitParams params(ToStorageKey("http://a.com/"), "bucket_a");
  params.expiration = clock->Now() - base::Days(1);

  ASSERT_FALSE(UpdateOrCreateBucket(params).has_value());

  // Create a new bucket.
  params.expiration = clock->Now() + base::Days(1);
  params.quota = 1000;
  ASSERT_OK_AND_ASSIGN(auto bucket, UpdateOrCreateBucket(params));
  EXPECT_EQ(bucket.expiration, params.expiration);
  EXPECT_EQ(bucket.quota, 1000);

  // Get/Update the same bucket. Verify expiration is updated, but quota is not.
  params.expiration = clock->Now() + base::Days(5);
  params.quota = 500;
  ASSERT_OK_AND_ASSIGN(bucket, UpdateOrCreateBucket(params));
  EXPECT_EQ(bucket.expiration, params.expiration);
  EXPECT_EQ(bucket.quota, 1000);

  // Verify that the bucket is clobbered due to being expired. In this case, the
  // new quota is respected.
  clock->Advance(base::Days(20));
  params.expiration = base::Time();
  ASSERT_OK_AND_ASSIGN(bucket, UpdateOrCreateBucket(params));
  EXPECT_EQ(bucket.expiration, params.expiration);
  EXPECT_EQ(bucket.quota, 500);

  QuotaDatabase::SetClockForTesting(nullptr);
}

TEST_F(QuotaManagerImplTest, UpdateOrCreateBucket_Overflow) {
  const int kPoolSize = 100;
  // This quota for the storage key implies only two buckets can be constructed.
  const int kPerStorageKeyQuota = 40 * 1024 * 1024;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  StorageKey storage_key = ToStorageKey("http://a.com/");

  EXPECT_TRUE(UpdateOrCreateBucket({storage_key, "bucket_a"}).has_value());
  EXPECT_TRUE(UpdateOrCreateBucket({storage_key, "bucket_b"}).has_value());
  EXPECT_THAT(UpdateOrCreateBucket({storage_key, "bucket_c"}),
              base::test::ErrorIs(QuotaError::kQuotaExceeded));

  // Default bucket shouldn't be limited by the quota.
  EXPECT_TRUE(
      UpdateOrCreateBucket({storage_key, kDefaultBucketName}).has_value());
}

// Make sure `EvictExpiredBuckets` deletes expired buckets.
TEST_F(QuotaManagerImplTest, EvictExpiredBuckets) {
  auto clock = std::make_unique<base::SimpleTestClock>();
  QuotaDatabase::SetClockForTesting(clock.get());
  clock->SetNow(base::Time::Now());

  BucketInitParams params(ToStorageKey("http://a.com/"), "bucket_a");
  params.expiration = clock->Now() + base::Days(1);
  ASSERT_OK_AND_ASSIGN(auto bucket, UpdateOrCreateBucket(params));

  BucketInitParams params_b(ToStorageKey("http://b.com/"), "bucket_b");
  params_b.expiration = clock->Now() + base::Days(10);
  ASSERT_OK_AND_ASSIGN(auto bucket_b, UpdateOrCreateBucket(params_b));

  // No specified expiration.
  BucketInitParams params_c(ToStorageKey("http://c.com/"), "bucket_c");
  ASSERT_OK_AND_ASSIGN(auto bucket_c, UpdateOrCreateBucket(params_c));

  clock->Advance(base::Days(5));

  // Evict expired buckets.
  base::test::TestFuture<QuotaStatusCode> future;
  quota_manager_impl_->EvictExpiredBuckets(future.GetCallback());
  EXPECT_EQ(QuotaStatusCode::kOk, future.Get());

  EXPECT_FALSE(GetBucketById(bucket.id).has_value());
  EXPECT_TRUE(GetBucketById(bucket_b.id).has_value());
  EXPECT_TRUE(GetBucketById(bucket_c.id).has_value());

  QuotaDatabase::SetClockForTesting(nullptr);
}

TEST_F(QuotaManagerImplTest, GetOrCreateBucketSync) {
  base::RunLoop loop;
  // Post the function call on a different thread to ensure that the
  // production DCHECK in GetOrCreateBucketSync passes.
  base::ThreadPool::PostTask(
      FROM_HERE, {base::MayBlock()}, base::BindLambdaForTesting([&]() {
        base::ScopedAllowBaseSyncPrimitivesForTesting allow;
        BucketInitParams params(ToStorageKey("http://b.com"), "bucket_b");
        // Ensure that the synchronous function returns a bucket.
        ASSERT_OK_AND_ASSIGN(
            auto bucket,
            quota_manager_impl_->proxy()->GetOrCreateBucketSync(params));
        BucketId created_bucket_id = bucket.id;

        // Ensure that the synchronous function does not create a new bucket
        // each time.
        ASSERT_OK_AND_ASSIGN(
            bucket,
            quota_manager_impl_->proxy()->GetOrCreateBucketSync(params));
        EXPECT_EQ(bucket.id, created_bucket_id);
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(QuotaManagerImplTest, GetBucket) {
  StorageKey storage_key = ToStorageKey("http://a.com/");
  std::string bucket_name = "bucket_a";

  ASSERT_OK_AND_ASSIGN(BucketInfo created_bucket,
                       CreateBucketForTesting(storage_key, bucket_name));

  ASSERT_OK_AND_ASSIGN(BucketInfo retrieved_bucket,
                       GetBucket(storage_key, bucket_name));
  EXPECT_EQ(created_bucket.id, retrieved_bucket.id);

  EXPECT_THAT(GetBucket(storage_key, "bucket_b"),
              base::test::ErrorIs(QuotaError::kNotFound));
  ASSERT_FALSE(is_db_disabled());
}

TEST_F(QuotaManagerImplTest, GetBucketById) {
  StorageKey storage_key = ToStorageKey("http://a.com/");
  std::string bucket_name = "bucket_a";

  ASSERT_OK_AND_ASSIGN(BucketInfo created_bucket,
                       CreateBucketForTesting(storage_key, bucket_name));

  ASSERT_OK_AND_ASSIGN(BucketInfo retrieved_bucket,
                       GetBucketById(created_bucket.id));
  EXPECT_EQ(created_bucket.id, retrieved_bucket.id);

  EXPECT_THAT(GetBucketById(BucketId::FromUnsafeValue(0)),
              base::test::ErrorIs(QuotaError::kNotFound));
  ASSERT_FALSE(is_db_disabled());
}

TEST_F(QuotaManagerImplTest, GetAllStorageKeys) {
  StorageKey storage_key_a = ToStorageKey("http://a.com/");
  StorageKey storage_key_b = ToStorageKey("http://b.com/");

  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_a,
                       CreateBucketForTesting(storage_key_a, "bucket_a"));

  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_b,
                       CreateBucketForTesting(storage_key_b, "bucket_b"));

  EXPECT_THAT(GetAllStorageKeys(),
              testing::UnorderedElementsAre(storage_key_a, storage_key_b));
}

TEST_F(QuotaManagerImplTest, GetAllStorageKeysWithDatabaseError) {
  disable_database_bootstrap(true);
  OpenDatabase();

  // Disable quota database for database error behavior.
  DisableQuotaDatabase();

  // Return empty set when error is encountered.
  EXPECT_TRUE(GetAllStorageKeys().empty());
}

TEST_F(QuotaManagerImplTest, QuotaDatabaseResultHistogram) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 123},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);
  base::HistogramTester histograms;

  ASSERT_TRUE(GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName)
                  .has_value());

  histograms.ExpectTotalCount("Quota.QuotaDatabaseError",
                              /*expected_count=*/0);

  // Corrupt QuotaDatabase so any future request returns a QuotaError.
  QuotaError corruption_error = CorruptDatabaseForTesting(
      base::BindOnce([](const base::FilePath& db_path) {
        ASSERT_TRUE(
            sql::test::CorruptIndexRootPage(db_path, "buckets_by_storage_key"));
      }));
  ASSERT_EQ(QuotaError::kNone, corruption_error);

  // Refetching the bucket with a corrupted database should return an error.
  EXPECT_THAT(GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName),
              base::test::ErrorIs(QuotaError::kDatabaseError));

  histograms.ExpectTotalCount("Quota.QuotaDatabaseError",
                              /*expected_count=*/1);
}

TEST_F(QuotaManagerImplTest, GetAllBuckets) {
  StorageKey storage_key_a = ToStorageKey("http://a.com/");
  StorageKey storage_key_b = ToStorageKey("http://b.com/");

  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_a,
                       CreateBucketForTesting(storage_key_a, "bucket_a"));

  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_b,
                       CreateBucketForTesting(storage_key_b, "bucket_b"));

  ASSERT_OK_AND_ASSIGN(std::set<BucketInfo> buckets, GetAllBuckets());
  EXPECT_EQ(2U, buckets.size());
  EXPECT_THAT(buckets, testing::Contains(bucket_a));
  EXPECT_THAT(buckets, testing::Contains(bucket_b));
}

TEST_F(QuotaManagerImplTest, GetBucketsForHost) {
  StorageKey host_a_storage_key_1 = ToStorageKey("http://a.com/");
  StorageKey host_a_storage_key_2 = ToStorageKey("https://a.com:123/");
  StorageKey host_b_storage_key = ToStorageKey("http://b.com/");

  ASSERT_OK_AND_ASSIGN(
      BucketInfo host_a_bucket_1,
      CreateBucketForTesting(host_a_storage_key_1, kDefaultBucketName));

  ASSERT_OK_AND_ASSIGN(BucketInfo host_a_bucket_2,
                       CreateBucketForTesting(host_a_storage_key_2, "test"));

  ASSERT_OK_AND_ASSIGN(
      BucketInfo host_b_bucket,
      CreateBucketForTesting(host_b_storage_key, kDefaultBucketName));

  ASSERT_OK_AND_ASSIGN(std::set<BucketInfo> buckets,
                       GetBucketsForHost("a.com"));
  EXPECT_EQ(2U, buckets.size());
  EXPECT_THAT(buckets, testing::Contains(host_a_bucket_1));
  EXPECT_THAT(buckets, testing::Contains(host_a_bucket_2));
}

TEST_F(QuotaManagerImplTest, GetBucketsForStorageKey) {
  StorageKey storage_key_a = ToStorageKey("http://a.com/");
  StorageKey storage_key_b = ToStorageKey("http://b.com/");
  StorageKey storage_key_c = ToStorageKey("http://c.com/");

  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_a1,
                       CreateBucketForTesting(storage_key_a, "bucket_a1"));

  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_a2,
                       CreateBucketForTesting(storage_key_a, "bucket_a2"));

  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_b,
                       CreateBucketForTesting(storage_key_b, "bucket_b"));

  ASSERT_OK_AND_ASSIGN(std::set<BucketInfo> buckets,
                       GetBucketsForStorageKey(storage_key_a));
  EXPECT_EQ(2U, buckets.size());
  EXPECT_THAT(buckets, testing::Contains(bucket_a1));
  EXPECT_THAT(buckets, testing::Contains(bucket_a2));

  ASSERT_OK_AND_ASSIGN(buckets, GetBucketsForStorageKey(storage_key_b));
  EXPECT_EQ(1U, buckets.size());
  EXPECT_THAT(buckets, testing::Contains(bucket_b));
}

TEST_F(QuotaManagerImplTest, GetBucketsForStorageKey_Expiration) {
  StorageKey storage_key = ToStorageKey("http://a.com/");

  auto clock = std::make_unique<base::SimpleTestClock>();
  QuotaDatabase::SetClockForTesting(clock.get());
  clock->SetNow(base::Time::Now());

  BucketInitParams params(storage_key, "bucket_1");
  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_1, UpdateOrCreateBucket(params));

  params.name = "bucket_2";
  params.expiration = clock->Now() + base::Days(1);
  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_2, UpdateOrCreateBucket(params));

  params.name = "bucket_3";
  ASSERT_OK_AND_ASSIGN(BucketInfo bucket_3, UpdateOrCreateBucket(params));

  clock->Advance(base::Days(2));

  ASSERT_OK_AND_ASSIGN(
      std::set<BucketInfo> buckets,
      GetBucketsForStorageKey(storage_key, /*delete_expired=*/true));
  ASSERT_EQ(1U, buckets.size());
  EXPECT_EQ(*buckets.begin(), bucket_1);

  QuotaDatabase::SetClockForTesting(nullptr);
}

TEST_F(QuotaManagerImplTest, EnforceQuota) {
  const int64_t kMbytes = 1024 * 1024;
  const int64_t kPoolSize = 100 * kMbytes;
  const int64_t kPerStorageKeyQuota = 50 * kMbytes;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  static const ClientBucketData kData[] = {
      {"https://foo.com/", "logs", /*usage=*/1000, /*quota=*/1025},
      {"https://foo.com/", "cache", /*usage=*/0},
      {"https://foo.com/", kDefaultBucketName, /*usage=*/3900},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  // Check a non-default bucket's custom quota is enforced.
  auto logs_bucket = GetBucket(ToStorageKey("https://foo.com/"), "logs");
  EXPECT_TRUE(CheckForSufficientSpace(logs_bucket->ToBucketLocator(), 20));
  EXPECT_FALSE(CheckForSufficientSpace(logs_bucket->ToBucketLocator(), 26));

  // Check the StorageKey quota is enforced for a non-default bucket.
  auto cache_bucket = GetBucket(ToStorageKey("https://foo.com/"), "cache");
  EXPECT_TRUE(
      CheckForSufficientSpace(cache_bucket->ToBucketLocator(), 10 * kMbytes));
  EXPECT_FALSE(
      CheckForSufficientSpace(cache_bucket->ToBucketLocator(), 60 * kMbytes));

  // Check the StorageKeyQuota is enforced for a default bucket.
  BucketLocator default_bucket =
      BucketLocator::ForDefaultBucket(ToStorageKey("https://foo.com/"));
  EXPECT_TRUE(CheckForSufficientSpace(default_bucket, 10 * kMbytes));
  EXPECT_FALSE(CheckForSufficientSpace(default_bucket, 60 * kMbytes));
}

TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Simple) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", "logs", 10},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  EXPECT_GT(result.quota, 0);
  int64_t quota_returned_for_foo = result.quota;

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://bar.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 0);
  EXPECT_EQ(result.quota, quota_returned_for_foo);
}

TEST_F(QuotaManagerImplTest, GetUsageAndQuota_SingleBucket) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", "logs", 10},
      {"http://foo.com/", "inbox", 60},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);

  // Initialize the logs bucket with a non-default quota.
  BucketInitParams params(ToStorageKey("http://foo.com/"), "logs");
  params.quota = 117;
  ASSERT_TRUE(UpdateOrCreateBucket(params).has_value());

  RegisterClientBucketData(fs_client, kData);

  {
    ASSERT_OK_AND_ASSIGN(
        BucketInfo bucket,
        UpdateOrCreateBucket({ToStorageKey("http://foo.com/"), "logs"}));
    auto result = GetUsageAndQuotaForBucket(bucket);
    EXPECT_EQ(result.status, QuotaStatusCode::kOk);
    EXPECT_EQ(result.usage, 10);
    EXPECT_EQ(result.quota, params.quota);
  }

  {
    ASSERT_OK_AND_ASSIGN(
        BucketInfo bucket,
        UpdateOrCreateBucket({ToStorageKey("http://foo.com/"), "inbox"}));
    auto result = GetUsageAndQuotaForBucket(bucket);
    EXPECT_EQ(result.status, QuotaStatusCode::kOk);
    EXPECT_EQ(result.usage, 60);
    EXPECT_EQ(result.quota, kDefaultPerStorageKeyQuota);
  }
}

TEST_F(QuotaManagerImplTest, GetUsage_NoClient) {
  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 0);

  EXPECT_EQ(
      0,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);

  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 0);
  EXPECT_EQ(global_usage_result.unlimited_usage, 0);
}

TEST_F(QuotaManagerImplTest, GetUsage_EmptyClient) {
  CreateAndRegisterClient(QuotaClientType::kFileSystem);

  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 0);

  EXPECT_EQ(
      0,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 0);
  EXPECT_EQ(global_usage_result.unlimited_usage, 0);
}

TEST_F(QuotaManagerImplTest, GetUsageAndQuota_MultiStorageKeys) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 10},
      {"http://foo.com:8080/", kDefaultBucketName, 20},
      {"http://bar.com/", "logs", 5},
      {"https://bar.com/", "notes", 7},
      {"http://baz.com/", "songs", 30},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  // This time explicitly set a global quota.
  const int kPoolSize = 100;
  const int kPerStorageKeyQuota = 20;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com:8080/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 20);

  // The host's quota should be its full portion of the global quota
  // since there's plenty of diskspace.
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://bar.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 5);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);
  result = GetUsageAndQuotaForWebApps(ToStorageKey("https://bar.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 7);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);
}

TEST_F(QuotaManagerImplTest, GetUsage_MultipleClients) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://bar.com/", kDefaultBucketName, 2},
  };
  static const ClientBucketData kData2[] = {
      {"https://foo.com/", kDefaultBucketName, 128},
      {"http://unlimited/", "logs", 512},
  };
  mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
  auto storage_capacity = GetStorageCapacity();

  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(idb_client, kData2);

  const int64_t kPoolSize = GetAvailableDiskSpaceForTest();
  const int64_t kPerStorageKeyQuota = kPoolSize / 5;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 1);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("https://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 128);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 512);
  EXPECT_EQ(result.quota, storage_capacity.available_space + result.usage);

  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 1 + 2 + 128 + 512);
  EXPECT_EQ(global_usage_result.unlimited_usage, 512);
}

TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_Simple) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
  };
  static const ClientBucketData kData2[] = {
      {"http://foo.com/", kDefaultBucketName, 4},
  };
  static const ClientBucketData kData3[] = {
      {"http://foo.com/", kDefaultBucketName, 8},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  MockQuotaClient* sw_client =
      CreateAndRegisterClient(QuotaClientType::kServiceWorkerCache);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(idb_client, kData2);
  RegisterClientBucketData(sw_client, kData3);

  blink::mojom::UsageBreakdown usage_breakdown_expected =
      blink::mojom::UsageBreakdown();
  auto result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(1 + 4 + 8, result.usage);
  usage_breakdown_expected.fileSystem = 1;
  usage_breakdown_expected.indexedDatabase = 4;
  usage_breakdown_expected.serviceWorkerCache = 8;
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));

  result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://bar.com/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(0, result.usage);
  usage_breakdown_expected.fileSystem = 0;
  usage_breakdown_expected.indexedDatabase = 0;
  usage_breakdown_expected.serviceWorkerCache = 0;
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));
}

TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_NoClient) {
  blink::mojom::UsageBreakdown usage_breakdown_expected =
      blink::mojom::UsageBreakdown();

  auto result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(0, result.usage);
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));

  auto usage = GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(0, usage.usage);
  EXPECT_TRUE(usage_breakdown_expected.Equals(*usage.breakdown));
}

TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_MultiStorageKeys) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 10},
      {"http://foo.com:8080/", "logs", 20},
      {"http://bar.com/", kDefaultBucketName, 5},
      {"https://bar.com/", kDefaultBucketName, 7},
      {"http://baz.com/", "logs", 30},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  blink::mojom::UsageBreakdown usage_breakdown_expected =
      blink::mojom::UsageBreakdown();
  auto result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(10, result.usage);
  usage_breakdown_expected.fileSystem = 10;
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));
  result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com:8080/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(20, result.usage);
  usage_breakdown_expected.fileSystem = 20;
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));

  result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://bar.com/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(5, result.usage);
  usage_breakdown_expected.fileSystem = 5;
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));
  result = GetUsageAndQuotaWithBreakdown(ToStorageKey("https://bar.com/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(7, result.usage);
  usage_breakdown_expected.fileSystem = 7;
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));
}

TEST_F(QuotaManagerImplTest, GetUsageWithBreakdown_MultipleClients) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://bar.com/", kDefaultBucketName, 2},
  };
  static const ClientBucketData kData2[] = {
      {"https://foo.com/", kDefaultBucketName, 128},
      {"http://unlimited/", "logs", 512},
  };
  mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(idb_client, kData2);

  blink::mojom::UsageBreakdown usage_breakdown_expected =
      blink::mojom::UsageBreakdown();
  auto result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(1, result.usage);
  usage_breakdown_expected.fileSystem = 1;
  usage_breakdown_expected.indexedDatabase = 0;
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));
  result = GetUsageAndQuotaWithBreakdown(ToStorageKey("https://foo.com/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(128, result.usage);
  usage_breakdown_expected.fileSystem = 0;
  usage_breakdown_expected.indexedDatabase = 128;
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));

  result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://unlimited/"));
  EXPECT_EQ(QuotaStatusCode::kOk, result.status);
  EXPECT_EQ(512, result.usage);
  usage_breakdown_expected.fileSystem = 0;
  usage_breakdown_expected.indexedDatabase = 512;
  EXPECT_TRUE(usage_breakdown_expected.Equals(*result.breakdown));
}

TEST_F(QuotaManagerImplTest, GetUsage_WithModify) {
  const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 10},
      {"http://bar.com/", kDefaultBucketName, 0},
      {"http://foo.com:1/", kDefaultBucketName, 20},
      {"https://foo.com/", kDefaultBucketName, 0},
  };
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com:1/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 20);

  ModifyDefaultBucketAndNotify(client, ToStorageKey("http://foo.com/"), 30);
  ModifyDefaultBucketAndNotify(client, ToStorageKey("http://foo.com:1/"), -5);
  ModifyDefaultBucketAndNotify(client, ToStorageKey("https://foo.com/"), 1);

  // Database call to ensure modification calls have completed.
  std::ignore = GetBucket(ToStorageKey("http://foo.com"), kDefaultBucketName);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10 + 30);
  int foo_usage = result.usage;
  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com:1/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 20 - 5);
  int foo1_usage = result.usage;

  ModifyDefaultBucketAndNotify(client, ToStorageKey("http://bar.com/"), 40);

  // Database call to ensure modification calls have completed.
  std::ignore = GetBucket(ToStorageKey("http://foo.com"), kDefaultBucketName);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://bar.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 40);

  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, foo_usage + foo1_usage + 40 + 1);
  EXPECT_EQ(global_usage_result.unlimited_usage, 0);
}

TEST_F(QuotaManagerImplTest, GetUsageAndQuota_WithAdditionalTasks) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 10},
      {"http://foo.com:8080/", kDefaultBucketName, 20},
      {"http://bar.com/", "logs", 13},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  const int kPoolSize = 100;
  const int kPerStorageKeyQuota = 20;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);
  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com:8080/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 20);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);

  set_additional_callback_count(0);
  RunAdditionalUsageAndQuotaTask(ToStorageKey("http://foo.com/"));
  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  RunAdditionalUsageAndQuotaTask(ToStorageKey("http://bar.com/"));
  task_environment_.RunUntilIdle();
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);
  EXPECT_EQ(2, additional_callback_count());
}

TEST_F(QuotaManagerImplTest, GetUsageAndQuota_NukeManager) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 10},
      {"http://foo.com:8080/", kDefaultBucketName, 20},
      {"http://bar.com/", kDefaultBucketName, 13},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  const int kPoolSize = 100;
  const int kPerStorageKeyQuota = 20;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  set_additional_callback_count(0);

  GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  RunAdditionalUsageAndQuotaTask(ToStorageKey("http://foo.com/"));
  RunAdditionalUsageAndQuotaTask(ToStorageKey("http://bar.com/"));

  base::test::TestFuture<QuotaStatusCode> future_foo;
  base::test::TestFuture<QuotaStatusCode> future_bar;
  quota_manager_impl()->DeleteHostData("foo.com", future_foo.GetCallback());
  quota_manager_impl()->DeleteHostData("bar.com", future_bar.GetCallback());

  // Nuke before waiting for callbacks.
  set_quota_manager_impl(nullptr);

  EXPECT_EQ(QuotaStatusCode::kErrorAbort, future_foo.Get());
  EXPECT_EQ(QuotaStatusCode::kErrorAbort, future_bar.Get());
}

TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Overbudget) {
  static const ClientBucketData kData[] = {
      {"http://usage1/", kDefaultBucketName, 1},
      {"http://usage10/", kDefaultBucketName, 10},
      {"http://usage200/", kDefaultBucketName, 200},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  const int kPoolSize = 100;
  const int kPerStorageKeyQuota = 20;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  // Provided diskspace is not tight, global usage does not affect the
  // quota calculations for an individual storage key, so despite global usage
  // in excess of our poolsize, we still get the nominal quota value.
  auto storage_capacity = GetStorageCapacity();
  EXPECT_LE(kMustRemainAvailableForSystem, storage_capacity.available_space);

  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://usage1/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 1);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://usage10/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://usage200/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 200);
  // Should be clamped to the nominal quota.
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);
}

TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Unlimited) {
  static const ClientBucketData kData[] = {
      {"http://usage10/", kDefaultBucketName, 10},
      {"http://usage50/", kDefaultBucketName, 50},
      {"http://unlimited/", "inbox", 4000},
  };
  mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
  auto storage_capacity = GetStorageCapacity();
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  // Test when not overbugdet.
  const int kPerStorageKeyQuotaFor1000 = 200;
  SetQuotaSettings(1000, kPerStorageKeyQuotaFor1000,
                   kMustRemainAvailableForSystem);
  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 10 + 50 + 4000);
  EXPECT_EQ(global_usage_result.unlimited_usage, 4000);

  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://usage10/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  EXPECT_EQ(result.quota, kPerStorageKeyQuotaFor1000);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://usage50/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 50);
  EXPECT_EQ(result.quota, kPerStorageKeyQuotaFor1000);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 4000);
  EXPECT_EQ(result.quota, storage_capacity.available_space + result.usage);

  auto client_result =
      GetUsageAndQuotaForStorageClient(ToStorageKey("http://unlimited/"));
  EXPECT_EQ(client_result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(client_result.usage, 0);
  EXPECT_EQ(client_result.quota, QuotaManagerImpl::kNoLimit);

  // Test when overbudgeted.
  const int kPerStorageKeyQuotaFor100 = 20;
  SetQuotaSettings(100, kPerStorageKeyQuotaFor100,
                   kMustRemainAvailableForSystem);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://usage10/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  EXPECT_EQ(result.quota, kPerStorageKeyQuotaFor100);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://usage50/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 50);
  EXPECT_EQ(result.quota, kPerStorageKeyQuotaFor100);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 4000);
  EXPECT_EQ(result.quota, storage_capacity.available_space + result.usage);

  client_result =
      GetUsageAndQuotaForStorageClient(ToStorageKey("http://unlimited/"));
  EXPECT_EQ(client_result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(client_result.usage, 0);
  EXPECT_EQ(client_result.quota, QuotaManagerImpl::kNoLimit);

  // Revoke the unlimited rights and make sure the change is noticed.
  mock_special_storage_policy()->Reset();
  mock_special_storage_policy()->NotifyCleared();

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 10 + 50 + 4000);
  EXPECT_EQ(global_usage_result.unlimited_usage, 0);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://usage10/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  EXPECT_EQ(result.quota, kPerStorageKeyQuotaFor100);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://usage50/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 50);
  EXPECT_EQ(result.quota, kPerStorageKeyQuotaFor100);

  result = GetUsageAndQuotaForWebApps(ToStorageKey("http://unlimited/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 4000);
  EXPECT_EQ(result.quota, kPerStorageKeyQuotaFor100);

  client_result =
      GetUsageAndQuotaForStorageClient(ToStorageKey("http://unlimited/"));
  EXPECT_EQ(client_result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(client_result.usage, 4000);
  EXPECT_EQ(client_result.quota, kPerStorageKeyQuotaFor100);
}

TEST_F(QuotaManagerImplTest, GetQuotaLowAvailableDiskSpace) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 100000},
      {"http://unlimited/", kDefaultBucketName, 4000000},
  };

  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  const int kPoolSize = 10000000;
  const int kPerStorageKeyQuota = kPoolSize / 5;

  // In here, we expect the low available space logic branch
  // to be ignored. Doing so should have QuotaManagerImpl return the same
  // per-host quota as what is set in QuotaSettings, despite being in a state of
  // low available space.
  const int kMustRemainAvailable =
      static_cast<int>(GetAvailableDiskSpaceForTest() - 65536);
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota, kMustRemainAvailable);

  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 100000);
  EXPECT_EQ(result.quota, kPerStorageKeyQuota);
}

TEST_F(QuotaManagerImplTest, GetUsage_Simple) {
  static const ClientBucketData kData[] = {
      {"http://bar.com/", kDefaultBucketName, 300},
      {"https://buz.com/", kDefaultBucketName, 4000},
      {"http://buz.com/", kDefaultBucketName, 50000},
      {"http://foo.com/", kDefaultBucketName, 7000000},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(300 + 4000 + 50000 + 7000000, global_usage_result.usage);
  EXPECT_EQ(global_usage_result.unlimited_usage, 0);

  EXPECT_EQ(
      4000,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("https://buz.com/")).usage);
  EXPECT_EQ(
      50000,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://buz.com/")).usage);
}

TEST_F(QuotaManagerImplTest, GetUsage_WithModification) {
  static const ClientBucketData kData[] = {
      {"http://bar.com/", kDefaultBucketName, 300},
      {"https://buz.com/", kDefaultBucketName, 4000},
      {"http://buz.com/", kDefaultBucketName, 50000},
      {"http://foo.com/", kDefaultBucketName, 7000000},
  };

  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 300 + 4000 + 50000 + 7000000);
  EXPECT_EQ(global_usage_result.unlimited_usage, 0);

  ModifyDefaultBucketAndNotify(client, ToStorageKey("http://foo.com/"), 1);

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 300 + 4000 + 50000 + 7000000 + 1);
  EXPECT_EQ(global_usage_result.unlimited_usage, 0);

  EXPECT_EQ(
      4000,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("https://buz.com/")).usage);
  EXPECT_EQ(
      50000,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://buz.com/")).usage);

  ModifyDefaultBucketAndNotify(client, ToStorageKey("http://buz.com/"),
                               900000000);

  EXPECT_EQ(
      4000,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("https://buz.com/")).usage);
  EXPECT_EQ(
      50000 + 900000000,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://buz.com/")).usage);
}

TEST_F(QuotaManagerImplTest, GetUsage_WithBucketModification) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://bar.com/", "logs", 100},
  };

  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  ASSERT_OK_AND_ASSIGN(
      auto foo_bucket,
      GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName));
  client->ModifyBucketAndNotify(foo_bucket.ToBucketLocator(), 80000000);

  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 1 + 100 + 80000000);
  EXPECT_EQ(global_usage_result.unlimited_usage, 0);

  EXPECT_EQ(
      100,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://bar.com/")).usage);

  ASSERT_OK_AND_ASSIGN(auto bar_bucket,
                       GetBucket(ToStorageKey("http://bar.com/"), "logs"));
  client->ModifyBucketAndNotify(bar_bucket.ToBucketLocator(), 900000000);

  EXPECT_EQ(
      100 + 900000000,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://bar.com/")).usage);
}

TEST_F(QuotaManagerImplTest, GetUsage_WithDeleteBucket) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://foo.com/", "secondbucket", 10000},
      {"http://foo.com:1/", kDefaultBucketName, 20},
      {"http://bar.com/", kDefaultBucketName, 4000},
  };
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  auto global_usage_result = GetGlobalUsage();
  int64_t predelete_global_tmp = global_usage_result.usage;

  const int64_t predelete_storage_key_tmp =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage;

  ASSERT_OK_AND_ASSIGN(auto bucket, GetBucket(ToStorageKey("http://foo.com/"),
                                              kDefaultBucketName));

  auto status = DeleteBucketData(bucket.ToBucketLocator(),
                                 {QuotaClientType::kFileSystem});
  EXPECT_EQ(status, QuotaStatusCode::kOk);

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, predelete_global_tmp - 1);

  EXPECT_EQ(
      predelete_storage_key_tmp - 1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
}

TEST_F(QuotaManagerImplTest, GetStorageCapacity) {
  auto storage_capacity = GetStorageCapacity();
  EXPECT_GE(storage_capacity.total_space, 0);
  EXPECT_GE(storage_capacity.available_space, 0);
}

TEST_F(QuotaManagerImplTest, EvictBucketData) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://foo.com:1/", "logs", 800000},
      {"http://foo.com/", "logs", 20},
      {"http://bar.com/", kDefaultBucketName, 4000},
  };
  static const ClientBucketData kData2[] = {
      {"http://foo.com/", kDefaultBucketName, 50000},
      {"http://foo.com:1/", "logs", 6000},
      {"https://foo.com/", kDefaultBucketName, 80},
      {"http://bar.com/", kDefaultBucketName, 9},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(idb_client, kData2);

  auto global_usage_result = GetGlobalUsage();
  int64_t predelete_global_tmp = global_usage_result.usage;

  const int64_t predelete_storage_key_tmp =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage;

  for (const ClientBucketData& data : kData1) {
    NotifyDefaultBucketAccessed(ToStorageKey(data.origin), base::Time::Now());
  }
  for (const ClientBucketData& data : kData2) {
    NotifyDefaultBucketAccessed(ToStorageKey(data.origin), base::Time::Now());
  }
  task_environment_.RunUntilIdle();

  // Default bucket eviction.
  ASSERT_OK_AND_ASSIGN(auto bucket, GetBucket(ToStorageKey("http://foo.com/"),
                                              kDefaultBucketName));

  EvictBucketData(bucket.ToBucketLocator());

  ASSERT_THAT(GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName),
              base::test::ErrorIs(QuotaError::kNotFound));

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(predelete_global_tmp - (1 + 50000), global_usage_result.usage);

  EXPECT_EQ(
      predelete_storage_key_tmp - (1 + 50000),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);

  // Non default bucket eviction.
  ASSERT_OK_AND_ASSIGN(bucket,
                       GetBucket(ToStorageKey("http://foo.com"), "logs"));

  EvictBucketData(bucket.ToBucketLocator());

  EXPECT_THAT(GetBucket(ToStorageKey("http://foo.com"), "logs"),
              base::test::ErrorIs(QuotaError::kNotFound));

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(predelete_global_tmp - (1 + 20 + 50000), global_usage_result.usage);

  EXPECT_EQ(
      predelete_storage_key_tmp - (1 + 20 + 50000),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
}

TEST_F(QuotaManagerImplTest, EvictBucketDataHistogram) {
  base::HistogramTester histograms;
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://bar.com/", kDefaultBucketName, 1},
  };
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  GetGlobalUsage();

  ASSERT_OK_AND_ASSIGN(auto bucket, GetBucket(ToStorageKey("http://foo.com"),
                                              kDefaultBucketName));

  EvictBucketData(bucket.ToBucketLocator());

  // Ensure use count and time since access are recorded.
  histograms.ExpectTotalCount(
      QuotaManagerImpl::kEvictedBucketAccessedCountHistogram, 1);
  histograms.ExpectBucketCount(
      QuotaManagerImpl::kEvictedBucketAccessedCountHistogram, 0, 1);
  histograms.ExpectTotalCount(
      QuotaManagerImpl::kEvictedBucketDaysSinceAccessHistogram, 1);

  // Change the use count.
  NotifyDefaultBucketAccessed(ToStorageKey("http://bar.com/"),
                              base::Time::Now());
  task_environment_.RunUntilIdle();

  GetGlobalUsage();

  ASSERT_OK_AND_ASSIGN(
      bucket, GetBucket(ToStorageKey("http://bar.com"), kDefaultBucketName));

  EvictBucketData(bucket.ToBucketLocator());

  // The new use count should be logged.
  histograms.ExpectTotalCount(
      QuotaManagerImpl::kEvictedBucketAccessedCountHistogram, 2);
  histograms.ExpectBucketCount(
      QuotaManagerImpl::kEvictedBucketAccessedCountHistogram, 1, 1);
  histograms.ExpectTotalCount(
      QuotaManagerImpl::kEvictedBucketDaysSinceAccessHistogram, 2);
}

TEST_F(QuotaManagerImplTest, EvictBucketDataWithDeletionError) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://foo.com:1/", kDefaultBucketName, 20},
      {"http://bar.com/", kDefaultBucketName, 4000},
  };
  static const int kNumberOfBuckets = 3;
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, (1 + 20 + 4000));

  EXPECT_EQ(
      1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
  EXPECT_EQ(
      20,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com:1/")).usage);

  for (const ClientBucketData& data : kData) {
    NotifyDefaultBucketAccessed(ToStorageKey(data.origin));
  }
  task_environment_.RunUntilIdle();

  ASSERT_OK_AND_ASSIGN(auto bucket, GetBucket(ToStorageKey("http://foo.com/"),
                                              kDefaultBucketName));
  client->AddBucketToErrorSet(bucket.ToBucketLocator());

  for (int i = 0; i < QuotaManagerImpl::kThresholdOfErrorsToBeDenylisted + 1;
       ++i) {
    EvictBucketData(bucket.ToBucketLocator());
  }

  // The default bucket for "http://foo.com/" should still be in the database.
  EXPECT_TRUE(GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName)
                  .has_value());

  for (size_t i = 0; i < kNumberOfBuckets - 1; ++i) {
    std::optional<BucketLocator> eviction_bucket = GetEvictionBucket();
    EXPECT_TRUE(eviction_bucket.has_value());
    // "http://foo.com/" should not be in the LRU list.
    EXPECT_NE(std::string("http://foo.com/"),
              eviction_bucket->storage_key.origin().GetURL().spec());
    DeleteBucketData(*eviction_bucket, AllQuotaClientTypes());
  }

  // Now the LRU list must be empty.
  std::optional<BucketLocator> eviction_bucket = GetEvictionBucket();
  EXPECT_FALSE(eviction_bucket.has_value());

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 1);

  EXPECT_EQ(
      1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
  EXPECT_EQ(
      0,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com:1/")).usage);
}

TEST_F(QuotaManagerImplTest, GetEvictionRoundInfo) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://foo.com:1/", kDefaultBucketName, 20},
      {"http://unlimited/", kDefaultBucketName, 4000},
  };

  mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  const int kPoolSize = 10000000;
  const int kPerStorageKeyQuota = kPoolSize / 5;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  GetEvictionRoundInfo();
  task_environment_.RunUntilIdle();
  EXPECT_EQ(QuotaStatusCode::kOk, status());
  EXPECT_EQ(21, usage());
  EXPECT_EQ(kPoolSize, settings().pool_size);
  EXPECT_LE(0, available_space());
}

TEST_F(QuotaManagerImplTest, DeleteHostDataNoClients) {
  EXPECT_EQ(DeleteHostData(std::string()), QuotaStatusCode::kOk);
}

TEST_F(QuotaManagerImplTest, DeleteHostDataSimple) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
  };
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  auto global_usage_result = GetGlobalUsage();
  const int64_t predelete_global = global_usage_result.usage;

  const int64_t predelete_storage_key =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage;

  EXPECT_EQ(DeleteHostData(std::string()), QuotaStatusCode::kOk);

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, predelete_global);

  EXPECT_EQ(
      predelete_storage_key,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);

  EXPECT_EQ(DeleteHostData("foo.com"), QuotaStatusCode::kOk);

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(predelete_global - 1, global_usage_result.usage);

  EXPECT_EQ(
      predelete_storage_key - 1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
}

TEST_F(QuotaManagerImplTest, DeleteHostDataMultiple) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://foo.com:1/", kDefaultBucketName, 20},
      {"http://bar.com/", kDefaultBucketName, 4000},
  };
  static const ClientBucketData kData2[] = {
      {"http://foo.com/", kDefaultBucketName, 50000},
      {"http://foo.com:1/", kDefaultBucketName, 6000},
      {"https://foo.com/", kDefaultBucketName, 80},
      {"http://bar.com/", kDefaultBucketName, 9},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(idb_client, kData2);

  auto global_usage_result = GetGlobalUsage();
  const int64_t predelete_global = global_usage_result.usage;

  const int64_t predelete_sk_foo =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage;
  const int64_t predelete_sk_sfoo =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("https://foo.com/")).usage;
  const int64_t predelete_sk_foo1 =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com:1/")).usage;
  const int64_t predelete_sk_bar =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://bar.com/")).usage;

  EXPECT_EQ(DeleteHostData("foo.com"), QuotaStatusCode::kOk);
  EXPECT_EQ(DeleteHostData("bar.com"), QuotaStatusCode::kOk);
  EXPECT_EQ(DeleteHostData("foo.com"), QuotaStatusCode::kOk);

  const BucketTableEntries& entries = DumpBucketTable();
  for (const auto& entry : entries) {
    std::optional<StorageKey> storage_key =
        StorageKey::Deserialize(entry->storage_key);
    ASSERT_TRUE(storage_key.has_value());

    EXPECT_NE(std::string("http://foo.com/"),
              storage_key.value().origin().GetURL().spec());
    EXPECT_NE(std::string("http://foo.com:1/"),
              storage_key.value().origin().GetURL().spec());
    EXPECT_NE(std::string("https://foo.com/"),
              storage_key.value().origin().GetURL().spec());
    EXPECT_NE(std::string("http://bar.com/"),
              std::move(storage_key).value().origin().GetURL().spec());
  }

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage,
            predelete_global - (1 + 20 + 4000 + 50000 + 6000 + 80 + 9));

  EXPECT_EQ(
      predelete_sk_foo - (1 + 50000),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
  EXPECT_EQ(
      predelete_sk_sfoo - (80),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("https://foo.com/")).usage);
  EXPECT_EQ(
      predelete_sk_foo1 - (20 + 6000),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com:1/")).usage);
  EXPECT_EQ(
      predelete_sk_bar - (4000 + 9),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://bar.com/")).usage);
}

TEST_F(QuotaManagerImplTest, DeleteBucketNoClients) {
  ASSERT_OK_AND_ASSIGN(auto bucket,
                       CreateBucketForTesting(ToStorageKey("http://foo.com"),
                                              kDefaultBucketName));
  EXPECT_EQ(DeleteBucketData(bucket.ToBucketLocator(), AllQuotaClientTypes()),
            QuotaStatusCode::kOk);
}

TEST_F(QuotaManagerImplTest, DeleteBucketDataMultiple) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://foo.com:1/", kDefaultBucketName, 20},
      {"http://bar.com/", kDefaultBucketName, 4000},
  };
  static const ClientBucketData kData2[] = {
      {"http://foo.com/", kDefaultBucketName, 50000},
      {"http://foo.com:1/", kDefaultBucketName, 6000},
      {"https://foo.com/", kDefaultBucketName, 80},
      {"http://bar.com/", kDefaultBucketName, 9},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(idb_client, kData2);

  ASSERT_OK_AND_ASSIGN(
      auto foo_bucket,
      GetBucket(ToStorageKey("http://foo.com"), kDefaultBucketName));

  ASSERT_OK_AND_ASSIGN(
      auto bar_bucket,
      GetBucket(ToStorageKey("http://bar.com"), kDefaultBucketName));

  auto global_usage_result = GetGlobalUsage();
  const int64_t predelete_global_tmp = global_usage_result.usage;

  const int64_t predelete_sk_foo_tmp =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage;
  const int64_t predelete_sk_sfoo_tmp =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("https://foo.com/")).usage;
  const int64_t predelete_sk_foo1_tmp =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com:1/")).usage;
  const int64_t predelete_sk_bar_tmp =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://bar.com/")).usage;

  for (const ClientBucketData& data : kData1) {
    NotifyDefaultBucketAccessed(ToStorageKey(data.origin), base::Time::Now());
  }
  for (const ClientBucketData& data : kData2) {
    NotifyDefaultBucketAccessed(ToStorageKey(data.origin), base::Time::Now());
  }
  task_environment_.RunUntilIdle();

  EXPECT_EQ(
      DeleteBucketData(foo_bucket.ToBucketLocator(), AllQuotaClientTypes()),
      QuotaStatusCode::kOk);
  EXPECT_EQ(
      DeleteBucketData(bar_bucket.ToBucketLocator(), AllQuotaClientTypes()),
      QuotaStatusCode::kOk);

  EXPECT_THAT(GetBucket(foo_bucket.storage_key, foo_bucket.name),
              base::test::ErrorIs(QuotaError::kNotFound));

  EXPECT_THAT(GetBucket(bar_bucket.storage_key, bar_bucket.name),
              base::test::ErrorIs(QuotaError::kNotFound));

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage,
            predelete_global_tmp - (1 + 4000 + 50000 + 9));

  EXPECT_EQ(
      predelete_sk_foo_tmp - (1 + 50000),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
  EXPECT_EQ(
      predelete_sk_sfoo_tmp,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("https://foo.com/")).usage);
  EXPECT_EQ(
      predelete_sk_foo1_tmp,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com:1/")).usage);
  EXPECT_EQ(
      predelete_sk_bar_tmp - (4000 + 9),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://bar.com/")).usage);
}

TEST_F(QuotaManagerImplTest, FindAndDeleteBucketData) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
      {"http://bar.com/", kDefaultBucketName, 4000},
  };
  static const ClientBucketData kData2[] = {
      {"http://foo.com/", kDefaultBucketName, 50000},
      {"http://bar.com/", kDefaultBucketName, 9},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(idb_client, kData2);

  ASSERT_OK_AND_ASSIGN(
      auto foo_bucket,
      GetBucket(ToStorageKey("http://foo.com"), kDefaultBucketName));

  ASSERT_OK_AND_ASSIGN(
      auto bar_bucket,
      GetBucket(ToStorageKey("http://bar.com"), kDefaultBucketName));

  // Check usage data before deletion.
  auto global_usage_result = GetGlobalUsage();
  ASSERT_EQ((1 + 9 + 4000 + 50000), global_usage_result.usage);
  const int64_t predelete_global_tmp = global_usage_result.usage;

  ASSERT_EQ(
      (1 + 50000),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
  ASSERT_EQ(
      (9 + 4000),
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://bar.com/")).usage);

  // Delete bucket for "http://foo.com/".
  EXPECT_EQ(FindAndDeleteBucketData(foo_bucket.storage_key, foo_bucket.name),
            QuotaStatusCode::kOk);

  EXPECT_THAT(GetBucket(foo_bucket.storage_key, foo_bucket.name),
              base::test::ErrorIs(QuotaError::kNotFound));

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, predelete_global_tmp - (1 + 50000));

  EXPECT_EQ(
      0,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);

  // Delete bucket for "http://bar.com/".
  EXPECT_EQ(FindAndDeleteBucketData(bar_bucket.storage_key, bar_bucket.name),
            QuotaStatusCode::kOk);

  EXPECT_THAT(GetBucket(bar_bucket.storage_key, bar_bucket.name),
              base::test::ErrorIs(QuotaError::kNotFound));

  global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 0);

  EXPECT_EQ(
      0,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://bar.com/")).usage);
}

TEST_F(QuotaManagerImplTest, FindAndDeleteBucketDataWithDBError) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 123},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);

  RegisterClientBucketData(fs_client, kData);

  // Check usage data before deletion.
  ASSERT_EQ(
      123,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);

  // Bucket lookup uses the `buckets_by_storage_key` index. So, we can corrupt
  // any other index, and SQLite will only detect the corruption when trying to
  // delete a bucket.
  QuotaError corruption_error = CorruptDatabaseForTesting(
      base::BindOnce([](const base::FilePath& db_path) {
        ASSERT_TRUE(sql::test::CorruptIndexRootPage(
            db_path, "buckets_by_last_accessed"));
      }));
  ASSERT_EQ(QuotaError::kNone, corruption_error);

  // Deleting the bucket will result in an error.
  EXPECT_NE(FindAndDeleteBucketData(ToStorageKey("http://foo.com"),
                                    kDefaultBucketName),
            QuotaStatusCode::kOk);

  auto global_usage_result = GetGlobalUsage();
  EXPECT_EQ(global_usage_result.usage, 0);

  EXPECT_EQ(
      0,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
}

TEST_F(QuotaManagerImplTest, GetDiskAvailabilityAndTempPoolSize) {
  ResetQuotaManagerImpl(/*is_incognito=*/false);

  base::test::TestFuture<int64_t, int64_t, int64_t> quota_internals_future;
  quota_manager_impl()->GetDiskAvailabilityAndTempPoolSize(
      quota_internals_future.GetCallback());
  std::tuple quota_internals_result = quota_internals_future.Take();

  int64_t available_space =
      static_cast<uint64_t>(GetAvailableDiskSpaceForTest());
  int64_t total_space = available_space * 2;

  EXPECT_EQ(total_space, std::get<0>(quota_internals_result));
  EXPECT_EQ(available_space, std::get<1>(quota_internals_result));
  EXPECT_EQ(kDefaultPoolSize, std::get<2>(quota_internals_result));
}

TEST_F(QuotaManagerImplTest, GetDiskAvailabilityAndTempPoolSize_Incognito) {
  // Test to make sure total_space and available_space are retrieved
  // as expected, without producing a crash.
  ResetQuotaManagerImpl(/*is_incognito=*/true);

  base::test::TestFuture<int64_t, int64_t, int64_t> quota_internals_future;
  quota_manager_impl()->GetDiskAvailabilityAndTempPoolSize(
      quota_internals_future.GetCallback());
  std::tuple quota_internals_result = quota_internals_future.Take();

  EXPECT_EQ(kDefaultPoolSize, std::get<0>(quota_internals_result));
  EXPECT_EQ(kDefaultPoolSize, std::get<1>(quota_internals_result));
  EXPECT_EQ(kDefaultPoolSize, std::get<2>(quota_internals_result));
}

TEST_F(QuotaManagerImplTest, NotifyAndLRUBucket) {
  static const ClientBucketData kData[] = {
      {"http://a.com/", kDefaultBucketName, 0},
      {"http://a.com:1/", kDefaultBucketName, 0},
      {"http://c.com/", kDefaultBucketName, 0},
  };
  QuotaDatabase::SetClockForTesting(task_environment_.GetMockClock());
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  task_environment_.FastForwardBy(base::Minutes(1));
  NotifyDefaultBucketAccessed(ToStorageKey("http://a.com/"),
                              task_environment_.GetMockClock()->Now());
  NotifyDefaultBucketAccessed(ToStorageKey("http://c.com/"),
                              task_environment_.GetMockClock()->Now());

  std::optional<BucketLocator> eviction_bucket = GetEvictionBucket();
  EXPECT_EQ("http://a.com:1/",
            eviction_bucket->storage_key.origin().GetURL().spec());

  DeleteBucketData(*eviction_bucket, AllQuotaClientTypes());
  eviction_bucket = GetEvictionBucket();
  EXPECT_EQ("http://a.com/",
            eviction_bucket->storage_key.origin().GetURL().spec());

  DeleteBucketData(*eviction_bucket, AllQuotaClientTypes());
  eviction_bucket = GetEvictionBucket();
  EXPECT_EQ("http://c.com/",
            eviction_bucket->storage_key.origin().GetURL().spec());
  QuotaDatabase::SetClockForTesting(nullptr);
}

TEST_F(QuotaManagerImplTest, GetBucketsForEviction) {
  static const ClientBucketData kData[] = {
      {"http://a.com/", kDefaultBucketName, 107},
      {"http://b.com/", kDefaultBucketName, 300},
      {"http://c.com/", kDefaultBucketName, 713},
  };
  QuotaDatabase::SetClockForTesting(task_environment_.GetMockClock());
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);
  GetGlobalUsage();

  task_environment_.FastForwardBy(base::Minutes(1));
  NotifyDefaultBucketAccessed(ToStorageKey("http://a.com/"),
                              task_environment_.GetMockClock()->Now());
  task_environment_.FastForwardBy(base::Minutes(1));
  NotifyDefaultBucketAccessed(ToStorageKey("http://b.com/"),
                              task_environment_.GetMockClock()->Now());
  task_environment_.FastForwardBy(base::Minutes(1));
  NotifyDefaultBucketAccessed(ToStorageKey("http://c.com/"),
                              task_environment_.GetMockClock()->Now());

  auto buckets = GetEvictionBuckets(110);
  EXPECT_THAT(buckets, testing::UnorderedElementsAre(
                           testing::Field(&BucketLocator::storage_key,
                                          ToStorageKey("http://a.com")),
                           testing::Field(&BucketLocator::storage_key,
                                          ToStorageKey("http://b.com"))));

  // Notify that the `bucket_a` is accessed. Now b is the LRU (and also happens
  // to satisfy the desire to evict 110b of data).
  NotifyDefaultBucketAccessed(ToStorageKey("http://a.com/"),
                              task_environment_.GetMockClock()->Now());
  buckets = GetEvictionBuckets(110);
  EXPECT_THAT(buckets,
              testing::UnorderedElementsAre(testing::Field(
                  &BucketLocator::storage_key, ToStorageKey("http://b.com"))));
  QuotaDatabase::SetClockForTesting(nullptr);
}

TEST_F(QuotaManagerImplTest, GetBucketsModifiedBetween) {
  static const ClientBucketData kData[] = {
      {"http://a.com/", kDefaultBucketName, 0},
      {"http://a.com:1/", kDefaultBucketName, 0},
      {"https://a.com/", kDefaultBucketName, 0},
      {"http://c.com/", kDefaultBucketName, 0},
  };
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  auto buckets = GetBucketsModifiedBetween(base::Time(), base::Time::Max());
  EXPECT_EQ(4U, buckets.size());

  base::Time time1 = client->IncrementMockTime();
  ModifyDefaultBucketAndNotify(client, ToStorageKey("http://a.com/"), 10);
  ModifyDefaultBucketAndNotify(client, ToStorageKey("http://a.com:1/"), 10);
  base::Time time2 = client->IncrementMockTime();
  ModifyDefaultBucketAndNotify(client, ToStorageKey("https://a.com/"), 10);
  ModifyDefaultBucketAndNotify(client, ToStorageKey("http://c.com/"), 10);
  base::Time time3 = client->IncrementMockTime();

  // Database call to ensure modification calls have completed.
  std::ignore = GetBucket(ToStorageKey("http://a.com"), kDefaultBucketName);

  buckets = GetBucketsModifiedBetween(time1, base::Time::Max());
  EXPECT_THAT(buckets, testing::UnorderedElementsAre(
                           testing::Field(&BucketLocator::storage_key,
                                          ToStorageKey("http://a.com")),
                           testing::Field(&BucketLocator::storage_key,
                                          ToStorageKey("http://a.com:1")),
                           testing::Field(&BucketLocator::storage_key,
                                          ToStorageKey("https://a.com")),
                           testing::Field(&BucketLocator::storage_key,
                                          ToStorageKey("http://c.com"))));

  buckets = GetBucketsModifiedBetween(time2, base::Time::Max());
  EXPECT_EQ(2U, buckets.size());

  buckets = GetBucketsModifiedBetween(time3, base::Time::Max());
  EXPECT_TRUE(buckets.empty());

  ModifyDefaultBucketAndNotify(client, ToStorageKey("http://a.com/"), 10);

  // Database call to ensure modification calls have completed.
  std::ignore = GetBucket(ToStorageKey("http://a.com"), kDefaultBucketName);

  buckets = GetBucketsModifiedBetween(time3, base::Time::Max());
  EXPECT_THAT(buckets,
              testing::UnorderedElementsAre(testing::Field(
                  &BucketLocator::storage_key, ToStorageKey("http://a.com/"))));
}

TEST_F(QuotaManagerImplTest, GetBucketsModifiedBetweenWithDatabaseError) {
  disable_database_bootstrap(true);
  OpenDatabase();

  // Disable quota database for database error behavior.
  DisableQuotaDatabase();

  auto buckets = GetBucketsModifiedBetween(base::Time(), base::Time::Max());

  // Return empty set when error is encountered.
  EXPECT_TRUE(buckets.empty());
}

TEST_F(QuotaManagerImplTest, DumpBucketTable) {
  // Dumping an unpopulated bucket table returns an empty vector.
  const BucketTableEntries& initial_entries = DumpBucketTable();
  EXPECT_TRUE(initial_entries.empty());

  const StorageKey kStorageKey1 = ToStorageKey("http://example1.com/");
  const StorageKey kStorageKey2 = ToStorageKey("http://example2.com/");
  std::ignore = CreateBucketForTesting(kStorageKey1, kDefaultBucketName);
  std::ignore = CreateBucketForTesting(kStorageKey2, kDefaultBucketName);

  NotifyDefaultBucketAccessed(kStorageKey1, base::Time::Now());
  NotifyDefaultBucketAccessed(kStorageKey2, base::Time::Now());
  NotifyDefaultBucketAccessed(kStorageKey2, base::Time::Now());
  task_environment_.RunUntilIdle();

  const BucketTableEntries& entries = DumpBucketTable();
  EXPECT_THAT(entries,
              testing::UnorderedElementsAre(
                  MatchesBucketTableEntry(kStorageKey1.Serialize(), 1),
                  MatchesBucketTableEntry(kStorageKey2.Serialize(), 2)));
}

TEST_F(QuotaManagerImplTest, RetrieveBucketsTable) {
  const StorageKey kStorageKey1 = ToStorageKey("http://example1.com/");
  const StorageKey kStorageKey2 = ToStorageKey("http://example2.com/");
  const base::Time kAccessTime = base::Time::Now();

  static const ClientBucketData kData[] = {
      {"http://example1.com/", kDefaultBucketName, 123},
      {"http://example2.com/", kDefaultBucketName, 456},
  };

  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(client, kData);

  NotifyDefaultBucketAccessed(kStorageKey1, kAccessTime);
  NotifyDefaultBucketAccessed(kStorageKey2, kAccessTime);
  const base::Time time1 = base::Time::Now();

  auto bucket1 = GetBucket(kStorageKey1, kDefaultBucketName);
  auto bucket2 = GetBucket(kStorageKey2, kDefaultBucketName);

  const std::vector<storage::mojom::BucketTableEntryPtr> bucket_table_entries =
      RetrieveBucketsTable();

  auto* entry1 = FindBucketTableEntry(bucket_table_entries, bucket1->id);
  EXPECT_TRUE(entry1);
  EXPECT_EQ(entry1->storage_key, kStorageKey1.Serialize());
  EXPECT_EQ(entry1->name, kDefaultBucketName);
  EXPECT_EQ(entry1->use_count, 1);
  EXPECT_EQ(entry1->last_accessed, kAccessTime);
  EXPECT_GE(entry1->last_modified, kAccessTime);
  EXPECT_LE(entry1->last_modified, time1);
  EXPECT_EQ(entry1->usage, 123);

  auto* entry2 = FindBucketTableEntry(bucket_table_entries, bucket2->id);
  EXPECT_TRUE(entry2);
  EXPECT_EQ(entry2->storage_key, kStorageKey2.Serialize());
  EXPECT_EQ(entry2->name, kDefaultBucketName);
  EXPECT_EQ(entry2->use_count, 1);
  EXPECT_EQ(entry2->last_accessed, kAccessTime);
  EXPECT_GE(entry1->last_modified, kAccessTime);
  EXPECT_LE(entry1->last_modified, time1);
  EXPECT_EQ(entry2->usage, 456);
}

TEST_F(QuotaManagerImplTest, DeleteSpecificClientTypeSingleBucket) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
  };
  static const ClientBucketData kData2[] = {
      {"http://foo.com/", kDefaultBucketName, 2},
  };
  static const ClientBucketData kData3[] = {
      {"http://foo.com/", kDefaultBucketName, 4},
  };
  static const ClientBucketData kData4[] = {
      {"http://foo.com/", kDefaultBucketName, 8},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* cache_client =
      CreateAndRegisterClient(QuotaClientType::kServiceWorkerCache);
  MockQuotaClient* sw_client =
      CreateAndRegisterClient(QuotaClientType::kServiceWorker);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(cache_client, kData2);
  RegisterClientBucketData(sw_client, kData3);
  RegisterClientBucketData(idb_client, kData4);

  ASSERT_OK_AND_ASSIGN(
      auto foo_bucket,
      GetBucket(ToStorageKey("http://foo.com"), kDefaultBucketName));

  const int64_t predelete_sk_foo_tmp =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage;

  DeleteBucketData(foo_bucket.ToBucketLocator(),
                   {QuotaClientType::kFileSystem});
  EXPECT_EQ(
      predelete_sk_foo_tmp - 1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);

  DeleteBucketData(foo_bucket.ToBucketLocator(),
                   {QuotaClientType::kServiceWorkerCache});
  EXPECT_EQ(
      predelete_sk_foo_tmp - 2 - 1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);

  DeleteBucketData(foo_bucket.ToBucketLocator(),
                   {QuotaClientType::kServiceWorker});
  EXPECT_EQ(
      predelete_sk_foo_tmp - 4 - 2 - 1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);

  DeleteBucketData(foo_bucket.ToBucketLocator(),
                   {QuotaClientType::kIndexedDatabase});
  EXPECT_EQ(
      predelete_sk_foo_tmp - 8 - 4 - 2 - 1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
}

TEST_F(QuotaManagerImplTest, DeleteMultipleClientTypesSingleBucket) {
  static const ClientBucketData kData1[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
  };
  static const ClientBucketData kData2[] = {
      {"http://foo.com/", kDefaultBucketName, 2},
  };
  static const ClientBucketData kData3[] = {
      {"http://foo.com/", kDefaultBucketName, 4},
  };
  static const ClientBucketData kData4[] = {
      {"http://foo.com/", kDefaultBucketName, 8},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  MockQuotaClient* cache_client =
      CreateAndRegisterClient(QuotaClientType::kServiceWorkerCache);
  MockQuotaClient* sw_client =
      CreateAndRegisterClient(QuotaClientType::kServiceWorker);
  MockQuotaClient* idb_client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(fs_client, kData1);
  RegisterClientBucketData(cache_client, kData2);
  RegisterClientBucketData(sw_client, kData3);
  RegisterClientBucketData(idb_client, kData4);

  ASSERT_OK_AND_ASSIGN(
      auto foo_bucket,
      GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName));

  const int64_t predelete_sk_foo_tmp =
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage;

  DeleteBucketData(
      foo_bucket.ToBucketLocator(),
      {QuotaClientType::kFileSystem, QuotaClientType::kServiceWorker});

  EXPECT_EQ(
      predelete_sk_foo_tmp - 4 - 1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);

  DeleteBucketData(foo_bucket.ToBucketLocator(),
                   {QuotaClientType::kServiceWorkerCache,
                    QuotaClientType::kIndexedDatabase});

  EXPECT_EQ(
      predelete_sk_foo_tmp - 8 - 4 - 2 - 1,
      GetStorageKeyUsageWithBreakdown(ToStorageKey("http://foo.com/")).usage);
}

TEST_F(QuotaManagerImplTest, GetUsageAndQuota_Incognito) {
  ResetQuotaManagerImpl(true);

  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 10},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  // Query global usage to warmup the usage tracker caching.
  GetGlobalUsage();

  const int kPoolSize = 1000;
  const int kPerStorageKeyQuota = kPoolSize / 5;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota, INT64_C(0));

  auto storage_capacity = GetStorageCapacity();
  EXPECT_EQ(storage_capacity.total_space, kPoolSize);
  EXPECT_EQ(storage_capacity.available_space, kPoolSize - 10);

  auto result = GetUsageAndQuotaForWebApps(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  EXPECT_GE(result.quota, kPerStorageKeyQuota);
}

TEST_F(QuotaManagerImplTest, GetUsageAndQuota_SessionOnly) {
  const StorageKey kEpheremalStorageKey = ToStorageKey("http://ephemeral/");
  mock_special_storage_policy()->AddSessionOnly(
      kEpheremalStorageKey.origin().GetURL());

  auto result = GetUsageAndQuotaForWebApps(kEpheremalStorageKey);
  EXPECT_EQ(quota_manager_impl()->settings().session_only_per_storage_key_quota,
            result.quota);
}

TEST_F(QuotaManagerImplTest, MaybeRunStoragePressureCallback) {
  bool callback_ran = false;
  auto cb = base::BindRepeating(
      [](bool* callback_ran, const StorageKey& storage_key) {
        *callback_ran = true;
      },
      &callback_ran);

  SetStoragePressureCallback(cb);

  int64_t kGBytes = QuotaManagerImpl::kMBytes * 1024;
  MaybeRunStoragePressureCallback(StorageKey(), 100 * kGBytes, 2 * kGBytes);
  task_environment_.RunUntilIdle();
  EXPECT_FALSE(callback_ran);

  MaybeRunStoragePressureCallback(StorageKey(), 100 * kGBytes, kGBytes);
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(callback_ran);
}

TEST_F(QuotaManagerImplTest, OverrideQuotaForStorageKey) {
  StorageKey storage_key = ToStorageKey("https://foo.com");
  std::unique_ptr<QuotaOverrideHandle> handle = GetQuotaOverrideHandle();

  base::RunLoop run_loop;
  handle->OverrideQuotaForStorageKey(
      storage_key, 5000,
      base::BindLambdaForTesting([&]() { run_loop.Quit(); }));
  run_loop.Run();

  auto result = GetUsageAndQuotaForWebApps(storage_key);
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 0);
  EXPECT_EQ(result.quota, 5000);
}

TEST_F(QuotaManagerImplTest, OverrideQuotaForStorageKey_Disable) {
  StorageKey storage_key = ToStorageKey("https://foo.com");
  std::unique_ptr<QuotaOverrideHandle> handle1 = GetQuotaOverrideHandle();
  std::unique_ptr<QuotaOverrideHandle> handle2 = GetQuotaOverrideHandle();

  base::RunLoop run_loop1;
  handle1->OverrideQuotaForStorageKey(
      storage_key, 5000,
      base::BindLambdaForTesting([&]() { run_loop1.Quit(); }));
  run_loop1.Run();

  auto result = GetUsageAndQuotaForWebApps(storage_key);
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.quota, 5000);

  base::RunLoop run_loop2;
  handle2->OverrideQuotaForStorageKey(
      storage_key, 9000,
      base::BindLambdaForTesting([&]() { run_loop2.Quit(); }));
  run_loop2.Run();

  result = GetUsageAndQuotaForWebApps(storage_key);
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.quota, 9000);

  base::RunLoop run_loop3;
  handle2->OverrideQuotaForStorageKey(
      storage_key, std::nullopt,
      base::BindLambdaForTesting([&]() { run_loop3.Quit(); }));
  run_loop3.Run();

  result = GetUsageAndQuotaForWebApps(storage_key);
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.quota, kDefaultPerStorageKeyQuota);
}

TEST_F(QuotaManagerImplTest, WithdrawQuotaOverride) {
  StorageKey storage_key = ToStorageKey("https://foo.com");
  std::unique_ptr<QuotaOverrideHandle> handle1 = GetQuotaOverrideHandle();
  std::unique_ptr<QuotaOverrideHandle> handle2 = GetQuotaOverrideHandle();

  base::RunLoop run_loop1;
  handle1->OverrideQuotaForStorageKey(
      storage_key, 5000,
      base::BindLambdaForTesting([&]() { run_loop1.Quit(); }));
  run_loop1.Run();

  auto result = GetUsageAndQuotaForWebApps(storage_key);
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.quota, 5000);

  base::RunLoop run_loop2;
  handle1->OverrideQuotaForStorageKey(
      storage_key, 8000,
      base::BindLambdaForTesting([&]() { run_loop2.Quit(); }));
  run_loop2.Run();

  result = GetUsageAndQuotaForWebApps(storage_key);
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.quota, 8000);

  // Quota should remain overridden if only one of the two handles withdraws
  // it's overrides
  handle2.reset();
  result = GetUsageAndQuotaForWebApps(storage_key);
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.quota, 8000);

  handle1.reset();
  task_environment_.RunUntilIdle();
  result = GetUsageAndQuotaForWebApps(storage_key);
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.quota, kDefaultPerStorageKeyQuota);
}

TEST_F(QuotaManagerImplTest, DeleteBucketData_QuotaManagerDeletedImmediately) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
  };
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(client, kData);

  ASSERT_OK_AND_ASSIGN(
      BucketInfo bucket,
      GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName));

  base::test::TestFuture<QuotaStatusCode> delete_bucket_data_future;
  quota_manager_impl_->DeleteBucketData(
      bucket.ToBucketLocator(), {QuotaClientType::kIndexedDatabase},
      delete_bucket_data_future.GetCallback());
  quota_manager_impl_.reset();
  EXPECT_NE(QuotaStatusCode::kOk, delete_bucket_data_future.Get());
}

TEST_F(QuotaManagerImplTest, DeleteBucketData_CallbackDeletesQuotaManager) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
  };
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(client, kData);

  ASSERT_OK_AND_ASSIGN(
      BucketInfo bucket,
      GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName));

  base::RunLoop run_loop;
  QuotaStatusCode delete_bucket_data_result = QuotaStatusCode::kUnknown;
  quota_manager_impl_->DeleteBucketData(
      bucket.ToBucketLocator(), {QuotaClientType::kIndexedDatabase},
      base::BindLambdaForTesting([&](QuotaStatusCode status_code) {
        quota_manager_impl_.reset();
        delete_bucket_data_result = status_code;
        run_loop.Quit();
      }));
  run_loop.Run();

  EXPECT_EQ(QuotaStatusCode::kOk, delete_bucket_data_result);
}

TEST_F(QuotaManagerImplTest, DeleteHostData_CallbackDeletesQuotaManager) {
  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 1},
  };
  MockQuotaClient* client =
      CreateAndRegisterClient(QuotaClientType::kIndexedDatabase);
  RegisterClientBucketData(client, kData);

  ASSERT_OK_AND_ASSIGN(
      BucketInfo bucket,
      GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName));

  auto status = DeleteBucketData(bucket.ToBucketLocator(),
                                 {QuotaClientType::kFileSystem});
  EXPECT_EQ(status, QuotaStatusCode::kOk);

  base::RunLoop run_loop;
  QuotaStatusCode delete_host_data_result = QuotaStatusCode::kUnknown;
  quota_manager_impl_->DeleteHostData(
      "foo.com", base::BindLambdaForTesting([&](QuotaStatusCode status_code) {
        quota_manager_impl_.reset();
        delete_host_data_result = status_code;
        run_loop.Quit();
      }));
  run_loop.Run();

  EXPECT_EQ(QuotaStatusCode::kOk, delete_host_data_result);
}

TEST_F(QuotaManagerImplTest, SimulateStoragePressure_Incognito) {
  bool callback_ran = false;

  auto cb = base::BindLambdaForTesting(
      [&callback_ran](const StorageKey& storage_key) { callback_ran = true; });

  SetStoragePressureCallback(cb);

  ResetQuotaManagerImpl(/*is_incognito=*/true);

  // This command should return and never execute the callback since it was
  // setup to be in Incognito.
  quota_manager_impl_->SimulateStoragePressure(
      url::Origin::Create(GURL("https://example.com")));

  EXPECT_FALSE(callback_ran);
}

TEST_F(QuotaManagerImplTest,
       QuotaManagerObserver_NotifiedOnAddedChangedAndDeleted) {
  auto clock = std::make_unique<base::SimpleTestClock>();
  QuotaDatabase::SetClockForTesting(clock.get());
  clock->SetNow(base::Time::Now());

  SetupQuotaManagerObserver();

  BucketInitParams params(ToStorageKey("http://a.com/"), "bucket_a");

  // Create bucket.
  ASSERT_OK_AND_ASSIGN(auto bucket, UpdateOrCreateBucket(params));
  RunUntilObserverNotifies();

  ASSERT_EQ(observer_notifications_.size(), 1U);
  ObserverNotification notification = observer_notifications_[0];
  ASSERT_EQ(notification.type, kCreateOrUpdate);
  ASSERT_EQ(notification.bucket_info, bucket);
  observer_notifications_.clear();

  params.persistent = true;
  params.expiration = clock->Now() + base::Days(1);

  // Update bucket.
  ASSERT_OK_AND_ASSIGN(auto updated_bucket, UpdateOrCreateBucket(params));
  RunUntilObserverNotifies();

  ASSERT_EQ(observer_notifications_.size(), 1U);
  notification = observer_notifications_[0];
  ASSERT_EQ(notification.type, kCreateOrUpdate);
  EXPECT_EQ(notification.bucket_info, updated_bucket);
  EXPECT_EQ(notification.bucket_info->persistent, params.persistent);
  EXPECT_EQ(notification.bucket_info->expiration, params.expiration);
  observer_notifications_.clear();

  // Delete bucket.
  auto status =
      DeleteBucketData(bucket.ToBucketLocator(), AllQuotaClientTypes());
  RunUntilObserverNotifies();

  ASSERT_EQ(status, QuotaStatusCode::kOk);
  ASSERT_EQ(observer_notifications_.size(), 1U);
  notification = observer_notifications_[0];
  ASSERT_EQ(notification.type, kDelete);
  EXPECT_EQ(notification.bucket_locator, updated_bucket.ToBucketLocator());

  QuotaDatabase::SetClockForTesting(nullptr);
}

TEST_F(QuotaManagerImplTest, QuotaManagerObserver_NotifiedOnExpired) {
  auto clock = std::make_unique<base::SimpleTestClock>();
  QuotaDatabase::SetClockForTesting(clock.get());
  clock->SetNow(base::Time::Now());

  SetupQuotaManagerObserver();

  BucketInitParams params(ToStorageKey("http://a.com/"), "bucket_a");
  params.expiration = clock->Now() + base::Days(5);

  ASSERT_OK_AND_ASSIGN(auto bucket, UpdateOrCreateBucket(params));
  RunUntilObserverNotifies();

  ASSERT_EQ(observer_notifications_.size(), 1U);
  ObserverNotification notification = observer_notifications_[0];
  ASSERT_EQ(notification.type, kCreateOrUpdate);
  ASSERT_EQ(notification.bucket_info, bucket);
  observer_notifications_.clear();

  clock->Advance(base::Days(20));
  base::test::TestFuture<QuotaStatusCode> future;
  quota_manager_impl_->EvictExpiredBuckets(future.GetCallback());
  EXPECT_EQ(QuotaStatusCode::kOk, future.Get());

  EXPECT_FALSE(GetBucketById(bucket.id).has_value());
  ASSERT_EQ(observer_notifications_.size(), 1U);
  notification = observer_notifications_[0];
  ASSERT_EQ(notification.type, kDelete);
  EXPECT_EQ(notification.bucket_locator, bucket.ToBucketLocator());

  QuotaDatabase::SetClockForTesting(nullptr);
}

TEST_F(QuotaManagerImplTest, StaticReportedQuota_NonBucket) {
  scoped_feature_list_.InitAndEnableFeature(
      storage::features::kStaticStorageQuota);

  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 80},
      {"http://unlimited/", kDefaultBucketName, 10},
  };
  mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  const int64_t kPoolSize = GetAvailableDiskSpaceForTest();
  const int64_t kPerStorageKeyQuota = kPoolSize / 5;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  // Static quota is returned for sites without unlimited storage permissions.
  auto result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 80);
  EXPECT_NE(result.quota, kPerStorageKeyQuota);

  int64_t initial_reported_quota = result.quota;
  int64_t additional_usage = initial_reported_quota + 100;
  ASSERT_OK_AND_ASSIGN(
      auto foo_bucket,
      GetBucket(ToStorageKey("http://foo.com/"), kDefaultBucketName));
  fs_client->ModifyBucketAndNotify(foo_bucket.ToBucketLocator(),
                                   additional_usage);
  result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"));
  // Quota increases with usage.
  EXPECT_GT(result.quota, initial_reported_quota);
  EXPECT_GT(result.quota, result.usage);
  EXPECT_EQ(result.usage, 80 + additional_usage);

  // Actual quota is returned for sites with unlimited storage permissions.
  result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://unlimited/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 10);
  EXPECT_EQ(result.quota, GetStorageCapacity().available_space + result.usage);
}

TEST_F(QuotaManagerImplTest, StaticReportedQuota_NonBucket_LowDisk) {
  scoped_feature_list_.InitAndEnableFeature(
      storage::features::kStaticStorageQuota);

  static const ClientBucketData kData[] = {
      {"http://foo.com/", kDefaultBucketName, 80},
  };
  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);
  RegisterClientBucketData(fs_client, kData);

  const int64_t kPoolSize = QuotaManagerImpl::kGBytes - 1;  // Just under 1 GiB.
  const int64_t kPerStorageKeyQuota = kPoolSize / 5;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota,
                   kMustRemainAvailableForSystem);

  // Static quota is returned for sites without unlimited storage permissions.
  auto result = GetUsageAndQuotaWithBreakdown(ToStorageKey("http://foo.com/"));
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 80);
  // Quota == usage + 1 GiB.
  EXPECT_EQ(result.quota, 80 + QuotaManagerImpl::kGBytes);
}

TEST_F(QuotaManagerImplTest, StaticReportedQuota_NonBucket_NukeManager) {
  scoped_feature_list_.InitAndEnableFeature(
      storage::features::kStaticStorageQuota);

  base::test::TestFuture<QuotaStatusCode, int64_t, int64_t,
                         blink::mojom::UsageBreakdownPtr>
      future;
  quota_manager_impl_->GetUsageAndReportedQuotaWithBreakdown(
      ToStorageKey("http://foo.com/"), future.GetCallback());

  // Nuke before waiting for callback.
  set_quota_manager_impl(nullptr);

  auto result = future.Take();
  EXPECT_EQ(std::get<0>(result), QuotaStatusCode::kUnknown);
  EXPECT_EQ(std::get<1>(result), 0);
  EXPECT_EQ(std::get<2>(result), 0);
}

TEST_F(QuotaManagerImplTest, StaticReportedQuota_Bucket) {
  scoped_feature_list_.InitAndEnableFeature(
      storage::features::kStaticStorageQuota);

  static const ClientBucketData kData[] = {
      {"http://foo.com/", "logs", 10},
      {"http://foo.com/", "inbox", 60},
      {"http://highrequestedquota.com/", "bucket", 0},
      {"http://unlimited/", "other", 0},
  };
  mock_special_storage_policy()->AddUnlimited(GURL("http://unlimited/"));
  auto storage_capacity = GetStorageCapacity();

  MockQuotaClient* fs_client =
      CreateAndRegisterClient(QuotaClientType::kFileSystem);

  // Initialize the logs bucket with a non-default quota.
  BucketInitParams low_quota_params(ToStorageKey("http://foo.com/"), "logs");
  low_quota_params.quota = 117;
  ASSERT_TRUE(UpdateOrCreateBucket(low_quota_params).has_value());

  // Initialize a bucket with quota > the max quota.
  BucketInitParams high_quota_params(
      ToStorageKey("http://highrequestedquota.com/"), "bucket");
  high_quota_params.quota = kDefaultPerStorageKeyQuota + 100;
  ASSERT_TRUE(UpdateOrCreateBucket(high_quota_params).has_value());

  RegisterClientBucketData(fs_client, kData);

  // Actual bucket quota is returned for bucket with non-default quota.
  {
    ASSERT_OK_AND_ASSIGN(
        BucketInfo bucket,
        UpdateOrCreateBucket({ToStorageKey("http://foo.com/"), "logs"}));
    auto result = GetUsageAndQuotaForBucket(bucket);
    EXPECT_EQ(result.status, QuotaStatusCode::kOk);
    EXPECT_EQ(result.usage, 10);
    EXPECT_EQ(result.quota, low_quota_params.quota);
  }

  // Static quota is returned for bucket with default quota and limited storage.
  {
    ASSERT_OK_AND_ASSIGN(
        BucketInfo bucket,
        UpdateOrCreateBucket({ToStorageKey("http://foo.com/"), "inbox"}));
    auto result = GetUsageAndQuotaForBucket(bucket);
    EXPECT_EQ(result.status, QuotaStatusCode::kOk);
    EXPECT_EQ(result.usage, 60);
    EXPECT_NE(result.quota, kDefaultPerStorageKeyQuota);

    int64_t initial_reported_quota = result.quota;
    int64_t additional_usage = initial_reported_quota + 100;
    fs_client->ModifyBucketAndNotify(bucket.ToBucketLocator(),
                                     additional_usage);
    result = GetUsageAndQuotaForBucket(bucket);
    EXPECT_EQ(result.status, QuotaStatusCode::kOk);

    // Quota increases with usage.
    EXPECT_GT(result.quota, initial_reported_quota);
    EXPECT_GT(result.quota, result.usage);
    EXPECT_EQ(result.usage, 60 + additional_usage);
  }

  // Requested quota is returned for bucket with requested quota > the max.
  {
    ASSERT_OK_AND_ASSIGN(
        BucketInfo bucket,
        UpdateOrCreateBucket(
            {ToStorageKey("http://highrequestedquota.com/"), "bucket"}));
    auto result = GetUsageAndQuotaForBucket(bucket);
    EXPECT_EQ(result.status, QuotaStatusCode::kOk);
    EXPECT_EQ(result.usage, 0);
    EXPECT_NE(result.quota, kDefaultPerStorageKeyQuota);
    EXPECT_EQ(result.quota, high_quota_params.quota);
  }

  // Actual quota is returned for bucket with default quota and unlimited
  // storage.
  {
    ASSERT_OK_AND_ASSIGN(
        BucketInfo bucket,
        UpdateOrCreateBucket({ToStorageKey("http://unlimited/"), "logs"}));
    auto result = GetUsageAndQuotaForBucket(bucket);
    EXPECT_EQ(result.status, QuotaStatusCode::kOk);
    EXPECT_EQ(result.usage, 0);
    EXPECT_EQ(result.quota, storage_capacity.available_space);
  }
}

TEST_F(QuotaManagerImplTest, StaticReportedQuota_Bucket_LowDisk) {
  scoped_feature_list_.InitAndEnableFeature(
      storage::features::kStaticStorageQuota);

  const int64_t kPoolSize =
      3 * QuotaManagerImpl::kGBytes + 1;  // Just over 3 GiB.
  const int64_t kPerStorageKeyQuota = kPoolSize / 5;
  SetQuotaSettings(kPoolSize, kPerStorageKeyQuota, 0);
  StorageKey storage_key = ToStorageKey("http://example.com/");
  std::string bucket_name = "bucket";

  ASSERT_OK_AND_ASSIGN(auto bucket,
                       UpdateOrCreateBucket({storage_key, bucket_name}));

  auto result = GetUsageAndQuotaForBucket(bucket);
  EXPECT_EQ(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 0);
  EXPECT_NE(result.quota, 4 * QuotaManagerImpl::kGBytes);
}

TEST_F(QuotaManagerImplTest, StaticReportedQuota_Bucket_BucketNotFound) {
  scoped_feature_list_.InitAndEnableFeature(
      storage::features::kStaticStorageQuota);

  StorageKey storage_key = ToStorageKey("http://example.com/");
  std::string bucket_name = "bucket";
  ASSERT_OK_AND_ASSIGN(auto bucket,
                       UpdateOrCreateBucket({storage_key, bucket_name}));

  FindAndDeleteBucketData(storage_key, bucket_name);

  auto result = GetUsageAndQuotaForBucket(bucket);
  EXPECT_NE(result.status, QuotaStatusCode::kOk);
  EXPECT_EQ(result.usage, 0);
  EXPECT_EQ(result.quota, 0);
}

}  // namespace storage
