// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/gtest/test_loop_fixture.h>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
#include "src/ledger/bin/app/constants.h"
#include "src/ledger/bin/app/disk_cleanup_manager_impl.h"
#include "src/ledger/bin/storage/fake/fake_db_factory.h"
#include "src/ledger/bin/testing/test_with_environment.h"

namespace ledger {
namespace {

using ::testing::ElementsAre;
using ::testing::IsEmpty;

class FakeDelegate : public PageEvictionManager::Delegate {
 public:
  void PageIsClosedAndSynced(
      fxl::StringView /*ledger_name*/, storage::PageIdView /*page_id*/,
      fit::function<void(storage::Status, PagePredicateResult)> callback)
      override {
    callback(storage::Status::OK, PagePredicateResult::YES);
  }

  void PageIsClosedOfflineAndEmpty(
      fxl::StringView ledger_name, storage::PageIdView page_id,
      fit::function<void(storage::Status, PagePredicateResult)> callback)
      override {
    callback(storage::Status::OK, closed_offline_empty);
  }

  void DeletePageStorage(
      fxl::StringView /*ledger_name*/, storage::PageIdView page_id,
      fit::function<void(storage::Status)> callback) override {
    deleted_pages.push_back(page_id.ToString());
    callback(storage::Status::OK);
  }

  std::vector<storage::PageId> deleted_pages;

  PagePredicateResult closed_offline_empty = PagePredicateResult::YES;
};

class DiskCleanupManagerTest : public TestWithEnvironment {
 public:
  DiskCleanupManagerTest()
      : db_factory_(environment_.dispatcher()),
        disk_cleanup_manager_(&environment_, &db_factory_,
                              DetachedPath(tmpfs_.root_fd())) {}

  // gtest::TestLoopFixture:
  void SetUp() override {
    disk_cleanup_manager_.Init();
    RunLoopUntilIdle();
    disk_cleanup_manager_.SetPageEvictionDelegate(&delegate_);
  }

 private:
  scoped_tmpfs::ScopedTmpFS tmpfs_;
  storage::fake::FakeDbFactory db_factory_;

 protected:
  FakeDelegate delegate_;
  DiskCleanupManagerImpl disk_cleanup_manager_;

  FXL_DISALLOW_COPY_AND_ASSIGN(DiskCleanupManagerTest);
};

TEST_F(DiskCleanupManagerTest, DontEvictNonEmptyPagesOnPageUnused) {
  std::string ledger_name = "ledger";
  storage::PageId page = std::string(::fuchsia::ledger::PAGE_ID_SIZE, '1');

  // The page cannot be evicted if its not empty and offline.
  disk_cleanup_manager_.OnPageOpened(ledger_name, page);
  delegate_.closed_offline_empty = PagePredicateResult::NO;
  disk_cleanup_manager_.OnPageUnused(ledger_name, page);
  RunLoopUntilIdle();
  EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
}

TEST_F(DiskCleanupManagerTest, DontEvictUnknownEmptyPagesOnPageUnused) {
  std::string ledger_name = "ledger";
  storage::PageId page = std::string(::fuchsia::ledger::PAGE_ID_SIZE, '1');

  // The page cannot be evicted if we can't determine whether it is empty and
  // offline.
  disk_cleanup_manager_.OnPageOpened(ledger_name, page);
  delegate_.closed_offline_empty = PagePredicateResult::PAGE_OPENED;
  disk_cleanup_manager_.OnPageUnused(ledger_name, page);
  RunLoopUntilIdle();
  EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
}

TEST_F(DiskCleanupManagerTest, EvictEmptyOfflinePagesOnPageUnused) {
  std::string ledger_name = "ledger";
  storage::PageId page = std::string(::fuchsia::ledger::PAGE_ID_SIZE, '1');

  // The page should be evicted is it is empty and offline.
  disk_cleanup_manager_.OnPageOpened(ledger_name, page);
  delegate_.closed_offline_empty = PagePredicateResult::YES;
  disk_cleanup_manager_.OnPageUnused(ledger_name, page);
  RunLoopUntilIdle();
  EXPECT_THAT(delegate_.deleted_pages, ElementsAre(page));
}

TEST_F(DiskCleanupManagerTest, DontEvictPagesOnPageClosed) {
  std::string ledger_name = "ledger";
  storage::PageId page = std::string(::fuchsia::ledger::PAGE_ID_SIZE, '1');

  disk_cleanup_manager_.OnPageOpened(ledger_name, page);
  delegate_.closed_offline_empty = PagePredicateResult::YES;
  disk_cleanup_manager_.OnPageClosed(ledger_name, page);
  RunLoopUntilIdle();
  EXPECT_THAT(delegate_.deleted_pages, IsEmpty());
}

}  // namespace
}  // namespace ledger
