// Copyright 2017 The Chromium 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 "components/feature_engagement/internal/persistent_event_store.h"

#include <map>

#include "base/files/file_path.h"
#include "base/optional.h"
#include "base/test/metrics/histogram_tester.h"
#include "components/feature_engagement/internal/proto/feature_event.pb.h"
#include "components/feature_engagement/internal/stats.h"
#include "components/feature_engagement/internal/test/event_util.h"
#include "components/leveldb_proto/proto_database.h"
#include "components/leveldb_proto/testing/fake_db.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace feature_engagement {

namespace {

void VerifyEventsInListAndMap(const std::map<std::string, Event>& map,
                              const std::vector<Event>& list) {
  ASSERT_EQ(map.size(), list.size());

  for (const auto& event : list) {
    const auto& it = map.find(event.name());
    ASSERT_NE(map.end(), it);
    test::VerifyEventsEqual(&event, &it->second);
  }
}

class PersistentEventStoreTest : public ::testing::Test {
 public:
  PersistentEventStoreTest() : db_(nullptr) {
    load_callback_ = base::Bind(&PersistentEventStoreTest::LoadCallback,
                                base::Unretained(this));
  }

  void TearDown() override {
    db_events_.clear();
    db_ = nullptr;
    store_.reset();
  }

 protected:
  void SetUpDB() {
    DCHECK(!db_);
    DCHECK(!store_);

    auto db = std::make_unique<leveldb_proto::test::FakeDB<Event>>(&db_events_);
    db_ = db.get();
    store_.reset(new PersistentEventStore(std::move(db)));
  }

  void LoadCallback(bool success, std::unique_ptr<std::vector<Event>> events) {
    load_successful_ = success;
    load_results_ = std::move(events);
  }

  // Callback results.
  base::Optional<bool> load_successful_;
  std::unique_ptr<std::vector<Event>> load_results_;

  EventStore::OnLoadedCallback load_callback_;
  std::map<std::string, Event> db_events_;
  leveldb_proto::test::FakeDB<Event>* db_;
  std::unique_ptr<EventStore> store_;
};

}  // namespace

TEST_F(PersistentEventStoreTest, SuccessfulInitAndLoadEmptyStore) {
  SetUpDB();

  base::HistogramTester histogram_tester;

  store_->Load(load_callback_);
  // The initialize should not trigger a response to the callback.
  db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK);
  EXPECT_FALSE(load_successful_.has_value());

  // The load should trigger a response to the callback.
  db_->LoadCallback(true);
  EXPECT_TRUE(load_successful_.value());

  // Validate that we have no entries.
  EXPECT_NE(nullptr, load_results_);
  EXPECT_TRUE(load_results_->empty());

  // Verify histograms.
  std::string suffix =
      stats::ToDbHistogramSuffix(stats::StoreType::EVENTS_STORE);
  histogram_tester.ExpectBucketCount("InProductHelp.Db.Init." + suffix, 1, 1);
  histogram_tester.ExpectBucketCount("InProductHelp.Db.Load." + suffix, 1, 1);
  histogram_tester.ExpectBucketCount("InProductHelp.Db.TotalEvents", 0, 1);
}

TEST_F(PersistentEventStoreTest, SuccessfulInitAndLoadWithEvents) {
  // Populate fake Event entries.
  Event event1;
  event1.set_name("event1");
  test::SetEventCountForDay(&event1, 1, 1);

  Event event2;
  event2.set_name("event2");
  test::SetEventCountForDay(&event2, 1, 3);
  test::SetEventCountForDay(&event2, 2, 5);

  db_events_.insert(std::pair<std::string, Event>(event1.name(), event1));
  db_events_.insert(std::pair<std::string, Event>(event2.name(), event2));

  SetUpDB();

  base::HistogramTester histogram_tester;

  // The initialize should not trigger a response to the callback.
  store_->Load(load_callback_);
  db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK);
  EXPECT_FALSE(load_successful_.has_value());

  // The load should trigger a response to the callback.
  db_->LoadCallback(true);
  EXPECT_TRUE(load_successful_.value());
  EXPECT_NE(nullptr, load_results_);

  // Validate that we have the two events that we expect.
  VerifyEventsInListAndMap(db_events_, *load_results_);

  // Verify histograms.
  std::string suffix =
      stats::ToDbHistogramSuffix(stats::StoreType::EVENTS_STORE);
  histogram_tester.ExpectBucketCount("InProductHelp.Db.Init." + suffix, 1, 1);
  histogram_tester.ExpectBucketCount("InProductHelp.Db.Load." + suffix, 1, 1);
  histogram_tester.ExpectBucketCount("InProductHelp.Db.TotalEvents", 3, 1);
}

TEST_F(PersistentEventStoreTest, SuccessfulInitBadLoad) {
  base::HistogramTester histogram_tester;
  SetUpDB();

  store_->Load(load_callback_);

  // The initialize should not trigger a response to the callback.
  db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK);
  EXPECT_FALSE(load_successful_.has_value());

  // The load will fail and should trigger the callback.
  db_->LoadCallback(false);
  EXPECT_FALSE(load_successful_.value());
  EXPECT_FALSE(store_->IsReady());

  // Histograms.
  std::string suffix =
      stats::ToDbHistogramSuffix(stats::StoreType::EVENTS_STORE);
  histogram_tester.ExpectBucketCount("InProductHelp.Db.Init." + suffix, 1, 1);
  histogram_tester.ExpectBucketCount("InProductHelp.Db.Load." + suffix, 0, 1);
  histogram_tester.ExpectTotalCount("InProductHelp.Db.TotalEvents", 0);
}

TEST_F(PersistentEventStoreTest, BadInit) {
  base::HistogramTester histogram_tester;
  SetUpDB();

  store_->Load(load_callback_);

  // The initialize will fail and should trigger the callback.
  db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kError);
  EXPECT_FALSE(load_successful_.value());
  EXPECT_FALSE(store_->IsReady());

  // Histograms.
  std::string suffix =
      stats::ToDbHistogramSuffix(stats::StoreType::EVENTS_STORE);
  histogram_tester.ExpectBucketCount("InProductHelp.Db.Init." + suffix, 0, 1);
  histogram_tester.ExpectTotalCount("InProductHelp.Db.Load." + suffix, 0);
  histogram_tester.ExpectTotalCount("InProductHelp.Db.TotalEvents", 0);
}

TEST_F(PersistentEventStoreTest, IsReady) {
  SetUpDB();
  EXPECT_FALSE(store_->IsReady());

  store_->Load(load_callback_);
  EXPECT_FALSE(store_->IsReady());

  db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK);
  EXPECT_FALSE(store_->IsReady());

  db_->LoadCallback(true);
  EXPECT_TRUE(store_->IsReady());
}

TEST_F(PersistentEventStoreTest, WriteEvent) {
  SetUpDB();

  store_->Load(load_callback_);
  db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK);
  db_->LoadCallback(true);

  Event event;
  event.set_name("event");
  test::SetEventCountForDay(&event, 1, 2);

  store_->WriteEvent(event);
  db_->UpdateCallback(true);

  EXPECT_EQ(1U, db_events_.size());

  const auto& it = db_events_.find("event");
  EXPECT_NE(db_events_.end(), it);
  test::VerifyEventsEqual(&event, &it->second);
}

TEST_F(PersistentEventStoreTest, WriteAndDeleteEvent) {
  SetUpDB();

  store_->Load(load_callback_);
  db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK);
  db_->LoadCallback(true);

  Event event;
  event.set_name("event");
  test::SetEventCountForDay(&event, 1, 2);

  store_->WriteEvent(event);
  db_->UpdateCallback(true);

  EXPECT_EQ(1U, db_events_.size());

  store_->DeleteEvent("event");
  db_->UpdateCallback(true);

  const auto& it = db_events_.find("event");
  EXPECT_EQ(db_events_.end(), it);
}

}  // namespace feature_engagement
