// Copyright 2016 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 "base/check_op.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/lifetime/browser_shutdown.h"
#include "chrome/browser/lifetime/termination_notification.h"
#include "chrome/browser/notifications/metrics/notification_metrics_logger.h"
#include "chrome/browser/notifications/metrics/notification_metrics_logger_factory.h"
#include "chrome/browser/notifications/notification_common.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/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
#include "chrome/browser/permissions/notifications_engagement_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/notification_content_detection/notification_content_detection_util.h"
#include "chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/permissions/features.h"
#include "components/permissions/permission_uma_util.h"
#include "components/permissions/permission_util.h"
#include "components/safe_browsing/content/browser/notification_content_detection/notification_content_detection_constants.h"
#include "components/safe_browsing/core/common/features.h"
#include "components/site_engagement/content/site_engagement_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_event_dispatcher.h"
#include "content/public/browser/permission_controller.h"
#include "content/public/browser/permission_descriptor_util.h"
#include "content/public/browser/permission_result.h"
#include "content/public/browser/platform_notification_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/persistent_notification_status.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "url/gurl.h"
#include "url/origin.h"

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#endif  // BUILDFLAG(ENABLE_BACKGROUND_MODE)

using content::BrowserThread;

namespace {

void RecordCloseResult(content::PersistentNotificationStatus status) {
  base::UmaHistogramEnumeration(
      "Notifications.PersistentWebNotificationCloseResult", status);
}

}  // namespace

PersistentNotificationHandler::PersistentNotificationHandler() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  on_app_terminating_subscription_ =
      browser_shutdown::AddAppTerminatingCallback(
          base::BindOnce(&PersistentNotificationHandler::OnAppTerminating,
                         weak_ptr_factory_.GetWeakPtr()));
}

PersistentNotificationHandler::~PersistentNotificationHandler() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
}

void PersistentNotificationHandler::OnClose(
    Profile* profile,
    const GURL& origin,
    const std::string& notification_id,
    bool by_user,
    base::OnceClosure completed_closure) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(origin.is_valid());

  if (browser_shutdown::HasShutdownStarted() ||
      g_browser_process->IsShuttingDown()) {
    // Do not prolong shutdown by running the 'notificationclose' event.
    RecordCloseResult(
        content::PersistentNotificationStatus::kCanceledByAppTerminating);
    std::move(completed_closure).Run();
    return;
  }

  // TODO(peter): Should we do permission checks prior to forwarding to the
  // NotificationEventDispatcher?

  // If we programmatically closed this notification, don't dispatch any event.
  //
  // TODO(crbug.com/352329050): there are circular dependencies between
  // NotificationMetricsLogger and PlatformNotificationService. Since the
  // service are only created lazily, and creation fails after the shutdown
  // phase, it is possible for the factory to return null. In that case, the
  // notification cannot have been closed programmatically.
  if (PlatformNotificationServiceImpl* service =
          PlatformNotificationServiceFactory::GetForProfile(profile);
      service && service->WasClosedProgrammatically(notification_id)) {
    std::move(completed_closure).Run();
    return;
  }

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
  close_event_keep_alive_state_.AddKeepAlive(profile);
#endif  // BUILDFLAG(ENABLE_BACKGROUND_MODE)

  NotificationMetricsLogger* metrics_logger =
      NotificationMetricsLoggerFactory::GetForBrowserContext(profile);
  if (by_user)
    metrics_logger->LogPersistentNotificationClosedByUser();
  else
    metrics_logger->LogPersistentNotificationClosedProgrammatically();

  int32_t callback_id = close_completed_callbacks_.Add(
      std::make_unique<base::OnceClosure>(std::move(completed_closure)));

  content::NotificationEventDispatcher::GetInstance()
      ->DispatchNotificationCloseEvent(
          profile, notification_id, origin, by_user,
          base::BindOnce(&PersistentNotificationHandler::OnCloseCompleted,
                         weak_ptr_factory_.GetWeakPtr(), profile, callback_id));
}

void PersistentNotificationHandler::OnCloseCompleted(
    Profile* profile,
    uint64_t close_completed_callback_id,
    content::PersistentNotificationStatus status) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  base::OnceClosure* completed_closure_pointer =
      close_completed_callbacks_.Lookup(close_completed_callback_id);
  if (!completed_closure_pointer) {
    // `OnAppTerminating()` already ran the callback.
    return;
  }

  base::OnceClosure completed_closure = std::move(*completed_closure_pointer);
  close_completed_callbacks_.Remove(close_completed_callback_id);

  RecordCloseResult(status);

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
  close_event_keep_alive_state_.RemoveKeepAlive(profile);
#endif  // BUILDFLAG(ENABLE_BACKGROUND_MODE)

  std::move(completed_closure).Run();
}

void PersistentNotificationHandler::OnClick(
    Profile* profile,
    const GURL& origin,
    const std::string& notification_id,
    const std::optional<int>& action_index,
    const std::optional<std::u16string>& reply,
    base::OnceClosure completed_closure) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  NotificationMetricsLogger* metrics_logger =
      NotificationMetricsLoggerFactory::GetForBrowserContext(profile);

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
  click_event_keep_alive_state_.AddKeepAlive(profile);
#endif  // BUILDFLAG(ENABLE_BACKGROUND_MODE)

  blink::mojom::PermissionStatus permission_status =
      profile->GetPermissionController()
          ->GetPermissionResultForOriginWithoutContext(
              content::PermissionDescriptorUtil::
                  CreatePermissionDescriptorForPermissionType(
                      blink::PermissionType::NOTIFICATIONS),
              url::Origin::Create(origin))
          .status;

  // Don't process click events when the |origin| doesn't have permission. This
  // can't be a DCHECK because of potential races with native notifications.
  if (permission_status != blink::mojom::PermissionStatus::GRANTED) {
    metrics_logger->LogPersistentNotificationClickWithoutPermission();

    OnClickCompleted(profile, notification_id, std::move(completed_closure),
                     content::PersistentNotificationStatus::kPermissionMissing);
    return;
  }

  if (action_index.has_value())
    metrics_logger->LogPersistentNotificationActionButtonClick();
  else
    metrics_logger->LogPersistentNotificationClick();

  // TODO(crbug.com/40280229)
  if (!origin.is_empty()) {
    auto* service =
        NotificationsEngagementServiceFactory::GetForProfile(profile);
    // This service might be missing for incognito profiles and in tests.
    if (service) {
      service->RecordNotificationInteraction(origin);
    }

    // Notification clicks are considered a form of engagement with the
    // |origin|, thus we log the interaction with the Site Engagement service.
    site_engagement::SiteEngagementService::Get(profile)
        ->HandleNotificationInteraction(origin);
  }

  content::NotificationEventDispatcher::GetInstance()
      ->DispatchNotificationClickEvent(
          profile, notification_id, origin, action_index, reply,
          base::BindOnce(&PersistentNotificationHandler::OnClickCompleted,
                         weak_ptr_factory_.GetWeakPtr(), profile,
                         notification_id, std::move(completed_closure)));

  // If there is a proposed disruptive notification revocation, report a false
  // positive due to user interacting with a notification. Disruptive are
  // notifications with high notification volume and low site engagement score.
  ukm::SourceId source_id = ukm::UkmRecorder::GetSourceIdForNotificationEvent(
      base::PassKey<PersistentNotificationHandler>(), origin);
  DisruptiveNotificationPermissionsManager::MaybeReportFalsePositive(
      profile, origin,
      DisruptiveNotificationPermissionsManager::FalsePositiveReason::
          kPersistentNotificationClick,
      source_id);
}

void PersistentNotificationHandler::OnClickCompleted(
    Profile* profile,
    const std::string& notification_id,
    base::OnceClosure completed_closure,
    content::PersistentNotificationStatus status) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  UMA_HISTOGRAM_ENUMERATION(
      "Notifications.PersistentWebNotificationClickResult", status);

  switch (status) {
    case content::PersistentNotificationStatus::kSuccess:
    case content::PersistentNotificationStatus::kServiceWorkerError:
    case content::PersistentNotificationStatus::kWaitUntilRejected:
      // There either wasn't a failure, or one that's in the developer's
      // control, so we don't act on the origin's behalf.
      break;
    case content::PersistentNotificationStatus::kServiceWorkerMissing:
    case content::PersistentNotificationStatus::kDatabaseError:
    case content::PersistentNotificationStatus::kPermissionMissing:
      // There was a failure that's out of the developer's control. The user now
      // observes a stuck notification, so let's close it for them.
      PlatformNotificationServiceFactory::GetForProfile(profile)
          ->ClosePersistentNotification(notification_id);
      break;

    case content::PersistentNotificationStatus::kCanceledByAppTerminating:
      // App termination must not cancel the click event.
      NOTREACHED();
  }

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
  click_event_keep_alive_state_.RemoveKeepAlive(profile);
#endif  // BUILDFLAG(ENABLE_BACKGROUND_MODE)

  std::move(completed_closure).Run();
}

void PersistentNotificationHandler::OnAppTerminating() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // Release all keep alives for currently running 'notificationclose' events.
  // This will allow browser shutdown to begin without waiting for the
  // 'notificationclose' events to complete.
#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
  close_event_keep_alive_state_.RemoveAllKeepAlives();
#endif

  // Like `OnCloseCompleted()` above, run the 'notificationclose' completed
  // callbacks after removing the keep alives.
  for (CloseCompletedCallbackMap::iterator it(&close_completed_callbacks_);
       !it.IsAtEnd(); it.Advance()) {
    RecordCloseResult(
        content::PersistentNotificationStatus::kCanceledByAppTerminating);
    std::move(*it.GetCurrentValue()).Run();
  }
  close_completed_callbacks_.Clear();
}

void PersistentNotificationHandler::DisableNotifications(Profile* profile,
                                                         const GURL& origin) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  permissions::PermissionUmaUtil::ScopedRevocationReporter
      scoped_revocation_reporter(
          profile, origin, origin, ContentSettingsType::NOTIFICATIONS,
          permissions::PermissionSourceUI::INLINE_SETTINGS);
#if BUILDFLAG(IS_ANDROID)
  // On Android, NotificationChannelsProviderAndroid does not support moving a
  // channel from ALLOW to BLOCK state, so simply delete the channel instead.
  NotificationPermissionContext::UpdatePermission(profile, origin,
                                                  CONTENT_SETTING_DEFAULT);
#else
  NotificationPermissionContext::UpdatePermission(profile, origin,
                                                  CONTENT_SETTING_BLOCK);
#endif
  // Remove `origin` from user allowlisted sites when user unsubscribes.
  auto* hcsm = HostContentSettingsMapFactory::GetForProfile(profile);
  if (hcsm && origin.is_valid()) {
    hcsm->SetWebsiteSettingCustomScope(
        ContentSettingsPattern::FromURLNoWildcard(origin),
        ContentSettingsPattern::Wildcard(),
        ContentSettingsType::ARE_SUSPICIOUS_NOTIFICATIONS_ALLOWLISTED_BY_USER,
        base::Value(base::Value::Dict().Set(
            safe_browsing::kIsAllowlistedByUserKey, false)));
  }
}

void PersistentNotificationHandler::OpenSettings(Profile* profile,
                                                 const GURL& origin) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  NotificationCommon::OpenNotificationSettings(profile, origin);
}

void PersistentNotificationHandler::ReportNotificationAsSafe(
    const std::string& notification_id,
    const GURL& url,
    Profile* profile) {
  OnMaybeReport(notification_id, url, profile, /*did_show_warning=*/true,
                /*did_user_unsubscribe=*/false);
}

void PersistentNotificationHandler::ReportWarnedNotificationAsSpam(
    const std::string& notification_id,
    const GURL& url,
    Profile* profile) {
  OnMaybeReport(notification_id, url, profile, /*did_show_warning=*/true,
                /*did_user_unsubscribe=*/true);
}

void PersistentNotificationHandler::ReportUnwarnedNotificationAsSpam(
    const std::string& notification_id,
    const GURL& url,
    Profile* profile) {
  OnMaybeReport(notification_id, url, profile, /*did_show_warning=*/false,
                /*did_user_unsubscribe=*/true);
}

void PersistentNotificationHandler::OnMaybeReport(
    const std::string& notification_id,
    const GURL& url,
    Profile* profile,
    bool did_show_warning,
    bool did_user_unsubscribe) {
  CHECK(profile);

  // In case the data volume becomes excessive, logging should happen at a
  // sampled rate. This rate is defined by the
  // `kReportNotificationContentDetectionDataRate` feature parameter.
  if (base::RandDouble() * 100 >
      safe_browsing::kReportNotificationContentDetectionDataRate.Get()) {
    return;
  }

  scoped_refptr<content::PlatformNotificationContext> notification_context =
      profile->GetStoragePartitionForUrl(url)->GetPlatformNotificationContext();
  if (!notification_context ||
      !OptimizationGuideKeyedServiceFactory::GetForProfile(profile)) {
    return;
  }

  blink::mojom::EngagementLevel engagement_level =
      blink::mojom::EngagementLevel::NONE;
  if (site_engagement::SiteEngagementService::Get(profile)) {
    engagement_level = site_engagement::SiteEngagementService::Get(profile)
                           ->GetEngagementLevel(url);
  }

  // Read notification data from database and upload as log to model quality
  // service.
  notification_context->ReadNotificationDataAndRecordInteraction(
      notification_id, url,
      content::PlatformNotificationContext::Interaction::NONE,
      base::BindOnce(
          &safe_browsing::SendNotificationContentDetectionDataToMQLSServer,
          OptimizationGuideKeyedServiceFactory::GetForProfile(profile)
              ->GetModelQualityLogsUploaderService()
              ->GetWeakPtr(),
          safe_browsing::NotificationContentDetectionMQLSMetadata(
              did_show_warning, did_user_unsubscribe, engagement_level)));
}

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)

PersistentNotificationHandler::NotificationKeepAliveState::
    NotificationKeepAliveState(KeepAliveOrigin keep_alive_origin,
                               ProfileKeepAliveOrigin profile_keep_alive_origin)
    : keep_alive_origin_(keep_alive_origin),
      profile_keep_alive_origin_(profile_keep_alive_origin) {}

PersistentNotificationHandler::NotificationKeepAliveState::
    ~NotificationKeepAliveState() = default;

void PersistentNotificationHandler::NotificationKeepAliveState::AddKeepAlive(
    Profile* profile) {
  // Ensure the browser and Profile stay alive while the event is processed. The
  // keep alives will be reset when all events have been acknowledged.
  if (pending_dispatch_events_++ == 0) {
    event_dispatch_keep_alive_ = std::make_unique<ScopedKeepAlive>(
        keep_alive_origin_, KeepAliveRestartOption::DISABLED);
  }
  // TODO(crbug.com/40159237): Remove IsOffTheRecord() when Incognito profiles
  // support refcounting.
  if (!profile->IsOffTheRecord() &&
      profile_pending_dispatch_events_[profile]++ == 0) {
    event_dispatch_profile_keep_alives_[profile] =
        std::make_unique<ScopedProfileKeepAlive>(profile,
                                                 profile_keep_alive_origin_);
  }
}

void PersistentNotificationHandler::NotificationKeepAliveState::RemoveKeepAlive(
    Profile* profile) {
  DCHECK_GT(pending_dispatch_events_, 0);
  // Reset the keep alive if all in-flight events have been processed.
  if (--pending_dispatch_events_ == 0)
    event_dispatch_keep_alive_.reset();

  // TODO(crbug.com/40159237): Remove IsOffTheRecord() when Incognito profiles
  // support refcounting.
  if (!profile->IsOffTheRecord() &&
      --profile_pending_dispatch_events_[profile] == 0) {
    event_dispatch_profile_keep_alives_[profile].reset();
  }
}

void PersistentNotificationHandler::NotificationKeepAliveState::
    RemoveAllKeepAlives() {
  event_dispatch_keep_alive_.reset();
  event_dispatch_profile_keep_alives_.clear();
  pending_dispatch_events_ = 0;
  profile_pending_dispatch_events_.clear();
}

#endif  // BUILDFLAG(ENABLE_BACKGROUND_MODE)
