// Copyright 2013 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 "ui/message_center/message_center_stats_collector.h"

#include <stddef.h>

#include <string>

#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "ui/message_center/message_center.h"

namespace message_center {

MessageCenterStatsCollector::NotificationStats::NotificationStats() {}

MessageCenterStatsCollector::NotificationStats::NotificationStats(
    const std::string& id)
    : id_(id) {
  for (size_t i = 0; i < NOTIFICATION_ACTION_COUNT; i++) {
    actions_[i] = false;
  }
}

MessageCenterStatsCollector::NotificationStats::~NotificationStats() {}

void MessageCenterStatsCollector::NotificationStats::CollectAction(
    NotificationActionType type) {
  DCHECK(!id_.empty());

  UMA_HISTOGRAM_ENUMERATION("Notifications.Actions", type,
                            NOTIFICATION_ACTION_COUNT);
  actions_[type] = true;
}

void MessageCenterStatsCollector::NotificationStats::RecordAggregateStats() {
  DCHECK(!id_.empty());

  for (size_t i = 0; i < NOTIFICATION_ACTION_COUNT; i++) {
    if (!actions_[i])
      continue;
    UMA_HISTOGRAM_ENUMERATION("Notifications.PerNotificationActions",
                              static_cast<NotificationActionType>(i),
                              NOTIFICATION_ACTION_COUNT);
  }
}

MessageCenterStatsCollector::MessageCenterStatsCollector(
    MessageCenter* message_center)
    : message_center_(message_center) {
  message_center_->AddObserver(this);
}

MessageCenterStatsCollector::~MessageCenterStatsCollector() {
  message_center_->RemoveObserver(this);
}

void MessageCenterStatsCollector::OnNotificationAdded(
    const std::string& notification_id) {
  stats_[notification_id] = NotificationStats(notification_id);

  StatsCollection::iterator iter = stats_.find(notification_id);
  DCHECK(iter != stats_.end());

  stats_[notification_id].CollectAction(NOTIFICATION_ACTION_ADD);
}

void MessageCenterStatsCollector::OnNotificationRemoved(
    const std::string& notification_id,
    bool by_user) {
  StatsCollection::iterator iter = stats_.find(notification_id);
  if (iter == stats_.end())
    return;
  NotificationStats& notification_stat = iter->second;
  notification_stat.CollectAction(by_user
                                      ? NOTIFICATION_ACTION_CLOSE_BY_USER
                                      : NOTIFICATION_ACTION_CLOSE_BY_SYSTEM);
  notification_stat.RecordAggregateStats();
  stats_.erase(notification_id);
}

void MessageCenterStatsCollector::OnNotificationUpdated(
    const std::string& notification_id) {
  StatsCollection::iterator iter = stats_.find(notification_id);
  if (iter == stats_.end())
    return;
  NotificationStats& notification_stat = iter->second;

  notification_stat.CollectAction(NOTIFICATION_ACTION_UPDATE);
}

void MessageCenterStatsCollector::OnNotificationClicked(
    const std::string& notification_id,
    const base::Optional<int>& button_index,
    const base::Optional<base::string16>& reply) {
  StatsCollection::iterator iter = stats_.find(notification_id);
  if (iter == stats_.end())
    return;
  NotificationStats& notification_stat = iter->second;

  notification_stat.CollectAction(button_index
                                      ? NOTIFICATION_ACTION_BUTTON_CLICK
                                      : NOTIFICATION_ACTION_CLICK);
}

void MessageCenterStatsCollector::OnNotificationSettingsClicked(bool handled) {
  base::RecordAction(base::UserMetricsAction("Notifications.ShowSiteSettings"));
}

void MessageCenterStatsCollector::OnNotificationDisplayed(
    const std::string& notification_id,
    const DisplaySource source) {
  StatsCollection::iterator iter = stats_.find(notification_id);
  if (iter == stats_.end())
    return;
  NotificationStats& notification_stat = iter->second;

  notification_stat.CollectAction(NOTIFICATION_ACTION_DISPLAY);
}

void MessageCenterStatsCollector::OnCenterVisibilityChanged(
    Visibility visibility) {
  switch (visibility) {
    case VISIBILITY_TRANSIENT:
      break;
    case VISIBILITY_MESSAGE_CENTER:
      base::RecordAction(
          base::UserMetricsAction("Notifications.ShowMessageCenter"));
      break;
    case VISIBILITY_SETTINGS:
      base::RecordAction(base::UserMetricsAction("Notifications.ShowSettings"));
      break;
  }
}

void MessageCenterStatsCollector::OnQuietModeChanged(bool in_quiet_mode) {
  if (in_quiet_mode) {
    base::RecordAction(base::UserMetricsAction("Notifications.Mute"));
  } else {
    base::RecordAction(base::UserMetricsAction("Notifications.Unmute"));
  }
}

}  // namespace message_center
