// Copyright (c) 2012 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.

#ifndef UI_MESSAGE_CENTER_NOTIFICATION_LIST_H_
#define UI_MESSAGE_CENTER_NOTIFICATION_LIST_H_

#include <stddef.h>

#include <list>
#include <map>
#include <set>
#include <string>

#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "ui/message_center/message_center_export.h"
#include "ui/message_center/notification_blocker.h"
#include "ui/message_center/public/cpp/notification_types.h"

namespace base {
class TimeDelta;
}

namespace gfx {
class Image;
}

namespace message_center {

namespace test {
class NotificationListTest;
}

class Notification;
class NotificationDelegate;
struct NotifierId;

// Comparers used to auto-sort the lists of Notifications.
struct MESSAGE_CENTER_EXPORT ComparePriorityTimestampSerial {
  bool operator()(Notification* n1, Notification* n2) const;
};

struct MESSAGE_CENTER_EXPORT CompareTimestampSerial {
  bool operator()(Notification* n1, Notification* n2) const;
};

// An adapter to allow use of the comparers above with std::unique_ptr.
template <typename PlainCompare>
struct UniquePtrCompare {
  template <typename T>
  bool operator()(const std::unique_ptr<T>& n1,
                  const std::unique_ptr<T>& n2) const {
    return PlainCompare()(n1.get(), n2.get());
  }
};

// A helper class to manage the list of notifications.
class MESSAGE_CENTER_EXPORT NotificationList {
 public:
  struct NotificationState {
    bool operator!=(const NotificationState& other) const;

    bool shown_as_popup = false;
    bool is_read = false;
  };

  // Auto-sorted set. Matches the order in which Notifications are shown in
  // Notification Center.
  using Notifications = std::set<Notification*, ComparePriorityTimestampSerial>;
  using OwnedNotifications =
      std::map<std::unique_ptr<Notification>,
               NotificationState,
               UniquePtrCompare<ComparePriorityTimestampSerial>>;

  // Auto-sorted set used to return the Notifications to be shown as popup
  // toasts.
  using PopupNotifications = std::set<Notification*, CompareTimestampSerial>;

  explicit NotificationList(MessageCenter* message_center);
  virtual ~NotificationList();

  // Makes a message "read". Collects the set of ids whose state have changed
  // and set to |udpated_ids|. NULL if updated ids don't matter.
  void SetNotificationsShown(const NotificationBlockers& blockers,
                             std::set<std::string>* updated_ids);

  void AddNotification(std::unique_ptr<Notification> notification);

  void UpdateNotificationMessage(
      const std::string& old_id,
      std::unique_ptr<Notification> new_notification);

  void RemoveNotification(const std::string& id);

  // Returns all notifications in this list.
  Notifications GetNotifications() const;

  // Returns all notifications that have a matching |notifier_id|.
  Notifications GetNotificationsByNotifierId(
      const NotifierId& notifier_id) const;

  // Returns all notifications that have a matching |app_id|.
  Notifications GetNotificationsByAppId(const std::string& app_id) const;

  // Returns true if the notification exists and was updated.
  bool SetNotificationIcon(const std::string& notification_id,
                           const gfx::Image& image);

  // Returns true if the notification exists and was updated.
  bool SetNotificationImage(const std::string& notification_id,
                            const gfx::Image& image);

  // Returns true if |id| matches a notification in the list and that
  // notification's type matches the given type.
  bool HasNotificationOfType(const std::string& id,
                             const NotificationType type) const;

  // Returns false if the first notification has been shown as a popup (which
  // means that all notifications have been shown).
  bool HasPopupNotifications(const NotificationBlockers& blockers) const;

  // Returns the recent notifications of the priority higher then LOW,
  // that have not been shown as a popup. kMaxVisiblePopupNotifications are
  // used to limit the number of notifications for the DEFAULT priority.
  // It also stores the list of notifications which are blocked by |blockers|
  // to |blocked|. |blocked| can be NULL if the caller doesn't care which
  // notifications are blocked.
  PopupNotifications GetPopupNotifications(const NotificationBlockers& blockers,
                                           std::list<std::string>* blocked);

  // Marks a specific popup item as shown. Set |mark_notification_as_read| to
  // true in case marking the notification as read too.
  void MarkSinglePopupAsShown(const std::string& id,
                              bool mark_notification_as_read);

  // Marks a specific popup item as displayed.
  void MarkSinglePopupAsDisplayed(const std::string& id);

  NotificationDelegate* GetNotificationDelegate(const std::string& id);

  bool quiet_mode() const { return quiet_mode_; }

  // Sets the current quiet mode status to |quiet_mode|.
  void SetQuietMode(bool quiet_mode);

  // Sets the current quiet mode to true. The quiet mode will expire in the
  // specified time-delta from now.
  void EnterQuietModeWithExpire(const base::TimeDelta& expires_in);

  // Returns the notification with the corresponding id. If not found, returns
  // NULL. Notification instance is owned by this list.
  Notification* GetNotificationById(const std::string& id);

  void PopupBlocked(const std::string& id);

  // Returns all visible notifications, in a (priority-timestamp) order.
  // Suitable for rendering notifications in a MessageCenter.
  Notifications GetVisibleNotifications(
      const NotificationBlockers& blockers) const;
  size_t NotificationCount(const NotificationBlockers& blockers) const;

 private:
  friend class NotificationListTest;
  FRIEND_TEST_ALL_PREFIXES(NotificationListTest,
                           TestPushingShownNotification);

  // Iterates through the list and returns the first notification matching |id|.
  OwnedNotifications::iterator GetNotification(const std::string& id);
  OwnedNotifications::const_iterator GetNotification(
      const std::string& id) const;

  void EraseNotification(OwnedNotifications::iterator iter);

  void PushNotification(std::unique_ptr<Notification> notification);

  MessageCenter* message_center_;  // owner
  OwnedNotifications notifications_;
  bool quiet_mode_;

  DISALLOW_COPY_AND_ASSIGN(NotificationList);
};

}  // namespace message_center

#endif // UI_MESSAGE_CENTER_NOTIFICATION_LIST_H_
