// Copyright 2014 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 "chrome/browser/notifications/notification_ui_manager_impl.h"

#include <memory>
#include <utility>

#include "base/logging.h"
#include "build/build_config.h"
#include "chrome/browser/notifications/fullscreen_notification_blocker.h"
#include "chrome/browser/notifications/popups_only_ui_controller.h"
#include "chrome/browser/notifications/profile_notification.h"
#include "chrome/browser/notifications/screen_lock_notification_blocker.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_types.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notifier_id.h"

using message_center::MessageCenter;
using message_center::NotifierId;

// static
std::unique_ptr<NotificationUIManager> NotificationUIManager::Create() {
  // If there's no MessageCenter, there should be no NotificationUIManager to
  // manage it.
  if (!message_center::MessageCenter::Get())
    return nullptr;

  return std::make_unique<NotificationUIManagerImpl>();
}

NotificationUIManagerImpl::NotificationUIManagerImpl()
    : system_observer_(this),
      popups_only_ui_controller_(std::make_unique<PopupsOnlyUiController>()) {
  auto* message_center = MessageCenter::Get();
  message_center->AddObserver(this);

  blockers_.push_back(
      std::make_unique<ScreenLockNotificationBlocker>(message_center));
  blockers_.push_back(
      std::make_unique<FullscreenNotificationBlocker>(message_center));
}

NotificationUIManagerImpl::~NotificationUIManagerImpl() {
  // The message center may have already been shut down (on Chrome OS).
  if (MessageCenter::Get())
    MessageCenter::Get()->RemoveObserver(this);

  profile_notifications_.clear();
}

////////////////////////////////////////////////////////////////////////////////
// NotificationUIManager

void NotificationUIManagerImpl::Add(
    const message_center::Notification& notification,
    Profile* profile) {
  // We won't have time to process and act on this notification.
  if (is_shutdown_started_)
    return;

  if (Update(notification, profile))
    return;

  auto profile_notification_ptr =
      std::make_unique<ProfileNotification>(profile, notification);
  ProfileNotification* profile_notification = profile_notification_ptr.get();

  // WARNING: You MUST use AddProfileNotification or update the message center
  // via the notification within a ProfileNotification object or the profile ID
  // will not be correctly set for ChromeOS.
  // Takes ownership of profile_notification.
  AddProfileNotification(std::move(profile_notification_ptr));

  MessageCenter::Get()->AddNotification(
      std::make_unique<message_center::Notification>(
          profile_notification->notification()));
}

bool NotificationUIManagerImpl::Update(
    const message_center::Notification& notification,
    Profile* profile) {
  const std::string profile_id = ProfileNotification::GetProfileNotificationId(
      notification.id(), NotificationUIManager::GetProfileID(profile));
  for (auto iter = profile_notifications_.begin();
       iter != profile_notifications_.end(); ++iter) {
    ProfileNotification* old_notification = (*iter).second.get();
    if (old_notification->notification().id() != profile_id)
      continue;

    // The ID should uniquely identify the notification, but as a sanity check
    // make sure we got the right origin URL and profile.
    DCHECK_EQ(old_notification->notification().origin_url(),
              notification.origin_url());
    DCHECK_EQ(old_notification->profile_id(),
              NotificationUIManager::GetProfileID(profile));

    // Changing the type from non-progress to progress does not count towards
    // the immediate update allowed in the message center.
    std::string old_id = old_notification->notification().id();

    // Add/remove notification in the local list but just update the same
    // one in MessageCenter.
    auto new_notification =
        std::make_unique<ProfileNotification>(profile, notification);
    const message_center::Notification& notification =
        new_notification->notification();
    // Delete the old one after the new one is created to ensure we don't run
    // out of KeepAlives.
    profile_notifications_.erase(old_id);
    profile_notifications_[notification.id()] = std::move(new_notification);

    // TODO(liyanhou): Add routing updated notifications to alternative
    // providers.

    // WARNING: You MUST use AddProfileNotification or update the message
    // center via the notification within a ProfileNotification object or the
    // profile ID will not be correctly set for ChromeOS.
    MessageCenter::Get()->UpdateNotification(
        old_id, std::make_unique<message_center::Notification>(notification));
    return true;
  }

  return false;
}

const message_center::Notification* NotificationUIManagerImpl::FindById(
    const std::string& id,
    ProfileID profile_id) const {
  std::string profile_notification_id =
      ProfileNotification::GetProfileNotificationId(id, profile_id);
  auto iter = profile_notifications_.find(profile_notification_id);
  if (iter == profile_notifications_.end())
    return nullptr;
  return &(iter->second->notification());
}

bool NotificationUIManagerImpl::CancelById(const std::string& id,
                                           ProfileID profile_id) {
  std::string profile_notification_id =
      ProfileNotification::GetProfileNotificationId(id, profile_id);
  // See if this ID hasn't been shown yet.
  // If it has been shown, remove it.
  auto iter = profile_notifications_.find(profile_notification_id);
  if (iter == profile_notifications_.end())
    return false;

  RemoveProfileNotification(iter->first);
  MessageCenter::Get()->RemoveNotification(profile_notification_id,
                                           /* by_user */ false);
  return true;
}

std::set<std::string> NotificationUIManagerImpl::GetAllIdsByProfile(
    ProfileID profile_id) {
  std::set<std::string> original_ids;
  for (const auto& pair : profile_notifications_) {
    if (pair.second->profile_id() == profile_id)
      original_ids.insert(pair.second->original_id());
  }

  return original_ids;
}

bool NotificationUIManagerImpl::CancelAllBySourceOrigin(const GURL& source) {
  // Same pattern as CancelById, but more complicated than the above
  // because there may be multiple notifications from the same source.
  bool removed = false;

  for (auto loopiter = profile_notifications_.begin();
       loopiter != profile_notifications_.end();) {
    auto curiter = loopiter++;
    if ((*curiter).second->notification().origin_url() == source) {
      const std::string id = curiter->first;
      RemoveProfileNotification(id);
      MessageCenter::Get()->RemoveNotification(id, /* by_user */ false);
      removed = true;
    }
  }
  return removed;
}

bool NotificationUIManagerImpl::CancelAllByProfile(ProfileID profile_id) {
  // Same pattern as CancelAllBySourceOrigin.
  bool removed = false;

  for (auto loopiter = profile_notifications_.begin();
       loopiter != profile_notifications_.end();) {
    auto curiter = loopiter++;
    if (profile_id == (*curiter).second->profile_id()) {
      const std::string id = curiter->first;
      RemoveProfileNotification(id);
      MessageCenter::Get()->RemoveNotification(id, /* by_user */ false);
      removed = true;
    }
  }
  return removed;
}

void NotificationUIManagerImpl::CancelAll() {
  MessageCenter::Get()->RemoveAllNotifications(
      false /* by_user */, message_center::MessageCenter::RemoveType::ALL);
}

void NotificationUIManagerImpl::StartShutdown() {
  is_shutdown_started_ = true;
  CancelAll();
  popups_only_ui_controller_.reset();
}

////////////////////////////////////////////////////////////////////////////////
// MessageCenter::Observer

void NotificationUIManagerImpl::OnNotificationRemoved(const std::string& id,
                                                      bool by_user) {
  RemoveProfileNotification(id);
}

void NotificationUIManagerImpl::ResetUiControllerForTest() {
  popups_only_ui_controller_.reset();
}

std::string NotificationUIManagerImpl::GetMessageCenterNotificationIdForTest(
    const std::string& id,
    Profile* profile) {
  return ProfileNotification::GetProfileNotificationId(id,
                                                       GetProfileID(profile));
}

////////////////////////////////////////////////////////////////////////////////
// private

void NotificationUIManagerImpl::AddProfileNotification(
    std::unique_ptr<ProfileNotification> profile_notification) {
  const message_center::Notification& notification =
      profile_notification->notification();
  std::string id = notification.id();
  // Notification ids should be unique.
  DCHECK(profile_notifications_.find(id) == profile_notifications_.end());
  profile_notifications_[id] = std::move(profile_notification);
}

void NotificationUIManagerImpl::RemoveProfileNotification(
    const std::string& notification_id) {
  auto it = profile_notifications_.find(notification_id);
  if (it == profile_notifications_.end())
    return;

  // Delay destruction of the ProfileNotification until current task is
  // completed. This must be done because this ProfileNotification might have
  // the one ScopedKeepAlive object that was keeping the browser alive, and
  // destroying it would result in:
  // a) A reentrant call to this class. Because every method in this class
  //    touches |profile_notifications_|, |profile_notifications_| must always
  //    be in a self-consistent state in moments where re-entrance might happen.
  // b) A crash like https://crbug.com/649971 because it can trigger
  //    shutdown process while we're still inside the call stack from UI
  //    framework.
  content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
                                     it->second.release());
  profile_notifications_.erase(it);
}

ProfileNotification* NotificationUIManagerImpl::FindProfileNotification(
    const std::string& id) const {
  auto iter = profile_notifications_.find(id);
  if (iter == profile_notifications_.end())
    return nullptr;

  return (*iter).second.get();
}
