// 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 "peridot/bin/ledger/app/page_usage_db.h"

#include <fuchsia/ledger/internal/cpp/fidl.h>
#include <zircon/syscalls.h>

#include "gtest/gtest.h"
#include "lib/callback/capture.h"
#include "lib/callback/set_when_called.h"
#include "lib/fxl/macros.h"
#include "peridot/bin/ledger/app/constants.h"
#include "peridot/bin/ledger/storage/fake/fake_db.h"
#include "peridot/bin/ledger/storage/public/types.h"
#include "peridot/bin/ledger/testing/test_with_environment.h"

namespace ledger {
namespace {

class PageUsageDbTest : public TestWithEnvironment {
 public:
  PageUsageDbTest()
      : db_(environment_.clock(), std::make_unique<storage::fake::FakeDb>(
                                      environment_.dispatcher())) {}

  ~PageUsageDbTest() override {}

  std::string RandomString(size_t size) {
    std::string result;
    result.resize(size);
    environment_.random()->Draw(&result);
    return result;
  }

 protected:
  PageUsageDb db_;

 private:
  FXL_DISALLOW_COPY_AND_ASSIGN(PageUsageDbTest);
};

TEST_F(PageUsageDbTest, GetPagesEmpty) {
  RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
    std::string ledger_name = "ledger_name";
    std::string page_id(::fuchsia::ledger::kPageIdSize, 'p');

    std::unique_ptr<storage::Iterator<const PageInfo>> pages;
    EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));

    EXPECT_EQ(storage::Status::OK, pages->GetStatus());
    EXPECT_FALSE(pages->Valid());
  });
}

TEST_F(PageUsageDbTest, MarkPageOpened) {
  RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
    std::string ledger_name = "ledger_name";
    std::string page_id(::fuchsia::ledger::kPageIdSize, 'p');

    // Open the same page.
    EXPECT_EQ(Status::OK, db_.MarkPageOpened(handler, ledger_name, page_id));

    // Expect to find a single entry with the opened page marker timestamp.
    std::unique_ptr<storage::Iterator<const PageInfo>> pages;
    EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));

    EXPECT_EQ(storage::Status::OK, pages->GetStatus());
    EXPECT_TRUE(pages->Valid());
    EXPECT_EQ(ledger_name, (*pages)->ledger_name);
    EXPECT_EQ(page_id, (*pages)->page_id);
    EXPECT_EQ(PageInfo::kOpenedPageTimestamp, (*pages)->timestamp);

    pages->Next();
    EXPECT_EQ(storage::Status::OK, pages->GetStatus());
    EXPECT_FALSE(pages->Valid());
  });
}

TEST_F(PageUsageDbTest, MarkPageOpenedAndClosed) {
  RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
    std::string ledger_name = "ledger_name";
    std::string page_id(::fuchsia::ledger::kPageIdSize, 'p');

    // Open and close the same page.
    EXPECT_EQ(Status::OK, db_.MarkPageOpened(handler, ledger_name, page_id));
    EXPECT_EQ(Status::OK, db_.MarkPageClosed(handler, ledger_name, page_id));

    // Expect to find a single entry with timestamp != the opened page marker
    // timestamp.
    std::unique_ptr<storage::Iterator<const PageInfo>> pages;
    EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));

    EXPECT_EQ(storage::Status::OK, pages->GetStatus());
    EXPECT_TRUE(pages->Valid());
    EXPECT_EQ(ledger_name, (*pages)->ledger_name);
    EXPECT_EQ(page_id, (*pages)->page_id);
    EXPECT_NE(PageInfo::kOpenedPageTimestamp, (*pages)->timestamp);

    pages->Next();
    EXPECT_EQ(storage::Status::OK, pages->GetStatus());
    EXPECT_FALSE(pages->Valid());
  });
}

TEST_F(PageUsageDbTest, MarkAllPagesClosed) {
  RunInCoroutine([&](coroutine::CoroutineHandler* handler) {
    std::string ledger_name = "ledger_name";
    int N = 5;
    std::string page_ids[N];
    for (int i = 0; i < N; ++i) {
      page_ids[i] = RandomString(::fuchsia::ledger::kPageIdSize);
    }

    // Open 5 pages.
    for (int i = 0; i < N; ++i) {
      EXPECT_EQ(Status::OK,
                db_.MarkPageOpened(handler, ledger_name, page_ids[i]));
    }

    // Close 1 of them.
    EXPECT_EQ(Status::OK,
              db_.MarkPageClosed(handler, ledger_name, page_ids[0]));

    // Expect to find 4 entries with timestamp equal to the opened page marker
    // timestamp.
    std::unique_ptr<storage::Iterator<const PageInfo>> pages;
    EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));

    int open_pages_count = 0;
    zx::time_utc page_0_timestamp(0);
    for (int i = 0; i < N; ++i) {
      EXPECT_EQ(storage::Status::OK, pages->GetStatus());
      ASSERT_TRUE(pages->Valid());
      EXPECT_EQ(ledger_name, (*pages)->ledger_name);
      if ((*pages)->page_id == page_ids[0]) {
        page_0_timestamp = (*pages)->timestamp;
        EXPECT_NE(PageInfo::kOpenedPageTimestamp, page_0_timestamp);
      } else {
        ++open_pages_count;
        EXPECT_EQ(PageInfo::kOpenedPageTimestamp, (*pages)->timestamp);
      }
      pages->Next();
    }
    EXPECT_EQ(N - 1, open_pages_count);

    EXPECT_EQ(storage::Status::OK, pages->GetStatus());
    EXPECT_FALSE(pages->Valid());

    // Call MarkAllPagesClosed and expect all 5 pages to be closed, 4 with the
    // same value.
    EXPECT_EQ(Status::OK, db_.MarkAllPagesClosed(handler));

    EXPECT_EQ(Status::OK, db_.GetPages(handler, &pages));
    zx::time_utc timestamp(PageInfo::kOpenedPageTimestamp);
    for (int i = 0; i < N; ++i) {
      EXPECT_EQ(storage::Status::OK, pages->GetStatus());
      ASSERT_TRUE(pages->Valid());
      EXPECT_EQ(ledger_name, (*pages)->ledger_name);
      if ((*pages)->page_id == page_ids[0]) {
        EXPECT_EQ(page_0_timestamp, (*pages)->timestamp);
      } else {
        // Expect from page 0, the others should have the same timestamp.
        EXPECT_NE(PageInfo::kOpenedPageTimestamp, (*pages)->timestamp);
        if (timestamp == PageInfo::kOpenedPageTimestamp) {
          timestamp = (*pages)->timestamp;
        } else {
          EXPECT_EQ(timestamp, (*pages)->timestamp);
        }
      }
      pages->Next();
    }
    EXPECT_EQ(N - 1, open_pages_count);
  });
}

}  // namespace
}  // namespace ledger
