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

#include "chrome/browser/notifications/persistent_notification_handler.h"

#include <memory>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/notifications/metrics/mock_notification_metrics_logger.h"
#include "chrome/browser/notifications/metrics/notification_metrics_logger_factory.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/notifications/notification_permission_context.h"
#include "chrome/browser/notifications/platform_notification_service_factory.h"
#include "chrome/browser/notifications/platform_notification_service_impl.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/permission_result.h"
#include "content/public/common/persistent_notification_status.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/mock_permission_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/notifications/notification_resources.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"

using ::testing::_;
using ::testing::Return;

namespace {

const char kExampleNotificationId[] = "example_notification_id";
const char kExampleOrigin[] = "https://example.com";

class TestingProfileWithPermissionManager : public TestingProfile {
 public:
  TestingProfileWithPermissionManager()
      : permission_manager_(
            std::make_unique<
                testing::NiceMock<content::MockPermissionManager>>()) {}
  TestingProfileWithPermissionManager(
      const TestingProfileWithPermissionManager&) = delete;
  TestingProfileWithPermissionManager& operator=(
      const TestingProfileWithPermissionManager&) = delete;

  ~TestingProfileWithPermissionManager() override = default;

  // Sets the notification permission status to |permission_status|.
  void SetNotificationPermissionStatus(
      blink::mojom::PermissionStatus permission_status) {
    ON_CALL(*permission_manager_, GetPermissionResultForOriginWithoutContext(
                                      blink::PermissionType::NOTIFICATIONS, _))
        .WillByDefault(Return(content::PermissionResult(
            permission_status, content::PermissionStatusSource::UNSPECIFIED)));
  }

  // TestingProfile overrides:
  content::PermissionControllerDelegate* GetPermissionControllerDelegate()
      override {
    return permission_manager_.get();
  }

 private:
  std::unique_ptr<content::MockPermissionManager> permission_manager_;
};

}  // namespace

class PersistentNotificationHandlerTest : public ::testing::Test {
 public:
  PersistentNotificationHandlerTest()
      : display_service_tester_(&profile_), origin_(kExampleOrigin) {}
  PersistentNotificationHandlerTest(const PersistentNotificationHandlerTest&) =
      delete;
  PersistentNotificationHandlerTest& operator=(
      const PersistentNotificationHandlerTest&) = delete;

  ~PersistentNotificationHandlerTest() override = default;

  // ::testing::Test overrides:
  void SetUp() override {
    HistoryServiceFactory::GetInstance()->SetTestingFactory(
        &profile_, HistoryServiceFactory::GetDefaultFactory());

    mock_logger_ = static_cast<MockNotificationMetricsLogger*>(
        NotificationMetricsLoggerFactory::GetInstance()
            ->SetTestingFactoryAndUse(
                &profile_,
                base::BindRepeating(
                    &MockNotificationMetricsLogger::FactoryForTests)));

    PlatformNotificationServiceFactory::GetForProfile(&profile_)
        ->ClearClosedNotificationsForTesting();
  }

 protected:
  content::BrowserTaskEnvironment task_environment_;
  TestingProfileWithPermissionManager profile_;
  NotificationDisplayServiceTester display_service_tester_;

  // The origin for which these tests are being run.
  GURL origin_;

  // Owned by the |profile_| as a keyed service.
  raw_ptr<MockNotificationMetricsLogger> mock_logger_ = nullptr;
};

TEST_F(PersistentNotificationHandlerTest, OnClick_WithoutPermission) {
  EXPECT_CALL(*mock_logger_, LogPersistentNotificationClickWithoutPermission());
  profile_.SetNotificationPermissionStatus(
      blink::mojom::PermissionStatus::DENIED);

  std::unique_ptr<NotificationHandler> handler =
      std::make_unique<PersistentNotificationHandler>();

  handler->OnClick(&profile_, origin_, kExampleNotificationId,
                   absl::nullopt /* action_index */, absl::nullopt /* reply */,
                   base::DoNothing());
}

TEST_F(PersistentNotificationHandlerTest,
       OnClick_CloseUnactionableNotifications) {
  // Show a notification for a particular origin.
  {
    base::RunLoop run_loop;
    display_service_tester_.SetNotificationAddedClosure(run_loop.QuitClosure());

    EXPECT_CALL(*mock_logger_, LogPersistentNotificationShown());

    PlatformNotificationServiceFactory::GetForProfile(&profile_)
        ->DisplayPersistentNotification(
            kExampleNotificationId, origin_ /* service_worker_scope */, origin_,
            blink::PlatformNotificationData(), blink::NotificationResources());

    run_loop.Run();
  }

  ASSERT_TRUE(display_service_tester_.GetNotification(kExampleNotificationId));

  // Revoke permission for any origin to display notifications.
  profile_.SetNotificationPermissionStatus(
      blink::mojom::PermissionStatus::DENIED);

  // Now simulate a click on the notification. It should be automatically closed
  // by the PersistentNotificationHandler.
  {
    EXPECT_CALL(*mock_logger_,
                LogPersistentNotificationClickWithoutPermission());

    display_service_tester_.SimulateClick(
        NotificationHandler::Type::WEB_PERSISTENT, kExampleNotificationId,
        absl::nullopt /* action_index */, absl::nullopt /* reply */);
  }

  EXPECT_FALSE(display_service_tester_.GetNotification(kExampleNotificationId));
}

TEST_F(PersistentNotificationHandlerTest, OnClose_ByUser) {
  EXPECT_CALL(*mock_logger_, LogPersistentNotificationClosedByUser());

  std::unique_ptr<NotificationHandler> handler =
      std::make_unique<PersistentNotificationHandler>();

  handler->OnClose(&profile_, origin_, kExampleNotificationId,
                   /* by_user= */ true, base::DoNothing());
}

TEST_F(PersistentNotificationHandlerTest, OnClose_Programmatically) {
  EXPECT_CALL(*mock_logger_, LogPersistentNotificationClosedProgrammatically());

  std::unique_ptr<NotificationHandler> handler =
      std::make_unique<PersistentNotificationHandler>();

  handler->OnClose(&profile_, origin_, kExampleNotificationId,
                   /* by_user= */ false, base::DoNothing());
}

TEST_F(PersistentNotificationHandlerTest, DisableNotifications) {
  std::unique_ptr<NotificationPermissionContext> permission_context =
      std::make_unique<NotificationPermissionContext>(&profile_);

  ASSERT_EQ(permission_context
                ->GetPermissionStatus(nullptr /* render_frame_host */, origin_,
                                      origin_)
                .content_setting,
            CONTENT_SETTING_ASK);

  std::unique_ptr<NotificationHandler> handler =
      std::make_unique<PersistentNotificationHandler>();
  handler->DisableNotifications(&profile_, origin_);

  ASSERT_EQ(permission_context
                ->GetPermissionStatus(nullptr /* render_frame_host */, origin_,
                                      origin_)
                .content_setting,
            CONTENT_SETTING_BLOCK);
}
