// 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/ntp_snippets/remote/prefetched_pages_tracker_impl.h"

#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/mock_callback.h"
#include "components/ntp_snippets/offline_pages/offline_pages_test_utils.h"
#include "components/offline_pages/core/client_namespace_constants.h"
#include "components/offline_pages/core/stub_offline_page_model.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ntp_snippets::test::FakeOfflinePageModel;
using offline_pages::MultipleOfflinePageItemCallback;
using offline_pages::OfflinePageItem;
using testing::_;
using testing::Eq;
using testing::SaveArg;
using testing::StrictMock;

namespace ntp_snippets {

namespace {

const int64_t kSystemDownloadId = 0;

class MockOfflinePageModel : public offline_pages::StubOfflinePageModel {
 public:
  ~MockOfflinePageModel() override = default;

  MOCK_METHOD2(GetPagesByNamespace,
               void(const std::string& name_space,
                    MultipleOfflinePageItemCallback callback));
};

OfflinePageItem CreateOfflinePageItem(const GURL& url,
                                      const std::string& name_space) {
  static int id = 0;
  ++id;
  return OfflinePageItem(
      url, id, offline_pages::ClientId(name_space, base::NumberToString(id)),
      base::FilePath::FromUTF8Unsafe(
          base::StringPrintf("some/folder/%d.mhtml", id)),
      0, base::Time::Now());
}

}  // namespace

class PrefetchedPagesTrackerImplTest : public ::testing::Test {
 public:
  PrefetchedPagesTrackerImplTest() = default;

  FakeOfflinePageModel* fake_offline_page_model() {
    return &fake_offline_page_model_;
  }

  MockOfflinePageModel* mock_offline_page_model() {
    return &mock_offline_page_model_;
  }

 private:
  FakeOfflinePageModel fake_offline_page_model_;
  StrictMock<MockOfflinePageModel> mock_offline_page_model_;
  DISALLOW_COPY_AND_ASSIGN(PrefetchedPagesTrackerImplTest);
};

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldRetrievePrefetchedEarlierSuggestionsOnInitialize) {
  (*fake_offline_page_model()->mutable_items()) = {
      CreateOfflinePageItem(GURL("http://prefetched.com"),
                            offline_pages::kSuggestedArticlesNamespace)};
  PrefetchedPagesTrackerImpl tracker(fake_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  ASSERT_FALSE(
      tracker.PrefetchedOfflinePageExists(GURL("http://not_added_url.com")));
  EXPECT_TRUE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldAddNewPrefetchedPagesWhenNotified) {
  fake_offline_page_model()->mutable_items()->clear();
  PrefetchedPagesTrackerImpl tracker(fake_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  ASSERT_FALSE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
  tracker.OfflinePageAdded(
      fake_offline_page_model(),
      CreateOfflinePageItem(GURL("http://prefetched.com"),
                            offline_pages::kSuggestedArticlesNamespace));
  EXPECT_TRUE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldIgnoreOtherTypesOfOfflinePagesWhenNotified) {
  fake_offline_page_model()->mutable_items()->clear();
  PrefetchedPagesTrackerImpl tracker(fake_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  ASSERT_FALSE(tracker.PrefetchedOfflinePageExists(
      GURL("http://manually_downloaded.com")));
  tracker.OfflinePageAdded(
      fake_offline_page_model(),
      CreateOfflinePageItem(GURL("http://manually_downloaded.com"),
                            offline_pages::kNTPSuggestionsNamespace));
  EXPECT_FALSE(tracker.PrefetchedOfflinePageExists(
      GURL("http://manually_downloaded.com")));
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldIgnoreOtherTypesOfOfflinePagesOnStartup) {
  (*fake_offline_page_model()->mutable_items()) = {
      CreateOfflinePageItem(GURL("http://manually_downloaded.com"),
                            offline_pages::kNTPSuggestionsNamespace)};
  PrefetchedPagesTrackerImpl tracker(fake_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  ASSERT_FALSE(tracker.PrefetchedOfflinePageExists(
      GURL("http://manually_downloaded.com")));
  EXPECT_FALSE(tracker.PrefetchedOfflinePageExists(
      GURL("http://manually_downloaded.com")));
}

TEST_F(PrefetchedPagesTrackerImplTest, ShouldDeletePrefetchedURLWhenNotified) {
  const OfflinePageItem item =
      CreateOfflinePageItem(GURL("http://prefetched.com"),
                            offline_pages::kSuggestedArticlesNamespace);
  (*fake_offline_page_model()->mutable_items()) = {item};
  PrefetchedPagesTrackerImpl tracker(fake_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  ASSERT_TRUE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
  tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
      item.offline_id, kSystemDownloadId, item.client_id,
      /*request_origin=*/"", item.original_url));
  EXPECT_FALSE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldIgnoreDeletionOfOtherTypeOfflinePagesWhenNotified) {
  const OfflinePageItem prefetched_item =
      CreateOfflinePageItem(GURL("http://prefetched.com"),
                            offline_pages::kSuggestedArticlesNamespace);
  // The URL is intentionally the same.
  const OfflinePageItem manually_downloaded_item = CreateOfflinePageItem(
      GURL("http://prefetched.com"), offline_pages::kNTPSuggestionsNamespace);
  (*fake_offline_page_model()->mutable_items()) = {prefetched_item,
                                                   manually_downloaded_item};
  PrefetchedPagesTrackerImpl tracker(fake_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  ASSERT_TRUE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
  tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
      manually_downloaded_item.offline_id, kSystemDownloadId,
      manually_downloaded_item.client_id,
      /*request_origin=*/"", manually_downloaded_item.original_url));
  EXPECT_TRUE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldReportAsNotInitializedBeforeReceivedArticles) {
  EXPECT_CALL(
      *mock_offline_page_model(),
      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _));
  PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));
  EXPECT_FALSE(tracker.IsInitialized());
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldReportAsInitializedAfterInitialization) {
  MultipleOfflinePageItemCallback offline_pages_callback;
  EXPECT_CALL(
      *mock_offline_page_model(),
      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _))
      .WillOnce([&](const std::string& name_space,
                    MultipleOfflinePageItemCallback callback) {
        offline_pages_callback = std::move(callback);
      });
  PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  ASSERT_FALSE(tracker.IsInitialized());
  std::move(offline_pages_callback).Run(std::vector<OfflinePageItem>());
  EXPECT_TRUE(tracker.IsInitialized());
}

TEST_F(PrefetchedPagesTrackerImplTest, ShouldCallCallbackAfterInitialization) {
  MultipleOfflinePageItemCallback offline_pages_callback;
  EXPECT_CALL(
      *mock_offline_page_model(),
      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _))
      .WillOnce([&](const std::string& name_space,
                    MultipleOfflinePageItemCallback callback) {
        offline_pages_callback = std::move(callback);
      });
  PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());

  base::MockCallback<base::OnceCallback<void()>>
      mock_initialization_completed_callback;
  tracker.Initialize(mock_initialization_completed_callback.Get());
  EXPECT_CALL(mock_initialization_completed_callback, Run());
  std::move(offline_pages_callback).Run(std::vector<OfflinePageItem>());
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldCallMultipleCallbacksAfterInitialization) {
  MultipleOfflinePageItemCallback offline_pages_callback;
  EXPECT_CALL(
      *mock_offline_page_model(),
      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _))
      .WillOnce([&](const std::string& name_space,
                    MultipleOfflinePageItemCallback callback) {
        offline_pages_callback = std::move(callback);
      });
  PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());

  base::MockCallback<base::OnceCallback<void()>>
      first_mock_initialization_completed_callback,
      second_mock_initialization_completed_callback;
  tracker.Initialize(first_mock_initialization_completed_callback.Get());
  tracker.Initialize(second_mock_initialization_completed_callback.Get());
  EXPECT_CALL(first_mock_initialization_completed_callback, Run());
  EXPECT_CALL(second_mock_initialization_completed_callback, Run());
  std::move(offline_pages_callback).Run(std::vector<OfflinePageItem>());
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldCallCallbackImmediatelyIfAlreadyInitialiazed) {
  MultipleOfflinePageItemCallback offline_pages_callback;
  EXPECT_CALL(
      *mock_offline_page_model(),
      GetPagesByNamespace(offline_pages::kSuggestedArticlesNamespace, _))
      .WillOnce([&](const std::string& name_space,
                    MultipleOfflinePageItemCallback callback) {
        offline_pages_callback = std::move(callback);
      });
  PrefetchedPagesTrackerImpl tracker(mock_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  std::move(offline_pages_callback).Run(std::vector<OfflinePageItem>());

  base::MockCallback<base::OnceCallback<void()>>
      mock_initialization_completed_callback;
  EXPECT_CALL(mock_initialization_completed_callback, Run());
  tracker.Initialize(mock_initialization_completed_callback.Get());
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldKeepPrefetchedURLAfterDuplicatePageDeleted) {
  const OfflinePageItem first_item =
      CreateOfflinePageItem(GURL("http://prefetched.com"),
                            offline_pages::kSuggestedArticlesNamespace);
  const OfflinePageItem second_item =
      CreateOfflinePageItem(GURL("http://prefetched.com"),
                            offline_pages::kSuggestedArticlesNamespace);
  (*fake_offline_page_model()->mutable_items()) = {first_item, second_item};
  PrefetchedPagesTrackerImpl tracker(fake_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  ASSERT_TRUE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));

  tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
      first_item.offline_id, kSystemDownloadId, first_item.client_id,
      /*request_origin=*/"", first_item.original_url));

  // Only one offline page (out of two) has been removed, the remaining one
  // should be reported here.
  EXPECT_TRUE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
}

TEST_F(PrefetchedPagesTrackerImplTest,
       ShouldDeletePrefetchedURLAfterAllItsPagesAreDeleted) {
  const OfflinePageItem first_item =
      CreateOfflinePageItem(GURL("http://prefetched.com"),
                            offline_pages::kSuggestedArticlesNamespace);
  const OfflinePageItem second_item =
      CreateOfflinePageItem(GURL("http://prefetched.com"),
                            offline_pages::kSuggestedArticlesNamespace);
  (*fake_offline_page_model()->mutable_items()) = {first_item, second_item};
  PrefetchedPagesTrackerImpl tracker(fake_offline_page_model());
  tracker.Initialize(base::BindOnce([] {}));

  ASSERT_TRUE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));

  tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
      first_item.offline_id, kSystemDownloadId, first_item.client_id,
      /*request_origin=*/"", first_item.original_url));

  ASSERT_TRUE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));

  tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
      second_item.offline_id, kSystemDownloadId, second_item.client_id,
      /*request_origin=*/"", second_item.original_url));

  // All offline pages have been removed, their absence should be reported here.
  EXPECT_FALSE(
      tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
}

}  // namespace ntp_snippets
