// Copyright 2018 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 "ash/system/screen_security/screen_security_notification_controller.h"

#include "ash/public/cpp/notification_utils.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notification_delegate.h"

using message_center::MessageCenter;
using message_center::Notification;

namespace ash {

// It is possible that we are capturing and sharing screen at the same time, so
// we cannot share the notification IDs for capturing and sharing.
const char kScreenCaptureNotificationId[] = "chrome://screen/capture";
const char kScreenShareNotificationId[] = "chrome://screen/share";
const char kNotifierScreenCapture[] = "ash.screen-capture";
const char kNotifierScreenShare[] = "ash.screen-share";

ScreenSecurityNotificationController::ScreenSecurityNotificationController() {
  Shell::Get()->AddShellObserver(this);
  Shell::Get()->system_tray_notifier()->AddScreenCaptureObserver(this);
  Shell::Get()->system_tray_notifier()->AddScreenShareObserver(this);
}

ScreenSecurityNotificationController::~ScreenSecurityNotificationController() {
  Shell::Get()->system_tray_notifier()->RemoveScreenShareObserver(this);
  Shell::Get()->system_tray_notifier()->RemoveScreenCaptureObserver(this);
  Shell::Get()->RemoveShellObserver(this);
}

void ScreenSecurityNotificationController::CreateNotification(
    const base::string16& message,
    bool is_capture) {
  message_center::RichNotificationData data;
  data.buttons.push_back(message_center::ButtonInfo(l10n_util::GetStringUTF16(
      is_capture ? IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_STOP
                 : IDS_ASH_STATUS_TRAY_SCREEN_SHARE_STOP)));
  // Only add "Change source" button when there is one session, since there
  // isn't a good UI to distinguish between the different sessions.
  if (is_capture && change_source_callback_ &&
      capture_stop_callbacks_.size() == 1) {
    data.buttons.push_back(message_center::ButtonInfo(l10n_util::GetStringUTF16(
        IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_CHANGE_SOURCE)));
  }

  auto delegate =
      base::MakeRefCounted<message_center::HandleNotificationClickDelegate>(
          base::BindRepeating(
              [](base::WeakPtr<ScreenSecurityNotificationController> controller,
                 bool is_capture, base::Optional<int> button_index) {
                if (!button_index)
                  return;

                if (*button_index == 0) {
                  controller->StopAllSessions(is_capture);
                  if (is_capture) {
                    Shell::Get()->metrics()->RecordUserMetricsAction(
                        UMA_STATUS_AREA_SCREEN_CAPTURE_NOTIFICATION_STOP);
                  }
                } else if (*button_index == 1) {
                  controller->ChangeSource();
                  if (is_capture) {
                    Shell::Get()->metrics()->RecordUserMetricsAction(
                        UMA_STATUS_AREA_SCREEN_CAPTURE_CHANGE_SOURCE);
                  }
                } else {
                  NOTREACHED();
                }
              },
              weak_ptr_factory_.GetWeakPtr(), is_capture));

  std::unique_ptr<Notification> notification = ash::CreateSystemNotification(
      message_center::NOTIFICATION_TYPE_SIMPLE,
      is_capture ? kScreenCaptureNotificationId : kScreenShareNotificationId,
      l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_SHARE_TITLE),
      message, base::string16() /* display_source */, GURL(),
      message_center::NotifierId(
          message_center::NotifierType::SYSTEM_COMPONENT,
          is_capture ? kNotifierScreenCapture : kNotifierScreenShare),
      data, std::move(delegate), kNotificationScreenshareIcon,
      message_center::SystemNotificationWarningLevel::NORMAL);
  notification->SetSystemPriority();
  notification->set_pinned(true);
  message_center::MessageCenter::Get()->AddNotification(
      std::move(notification));
}

void ScreenSecurityNotificationController::StopAllSessions(bool is_capture) {
  message_center::MessageCenter::Get()->RemoveNotification(
      is_capture ? kScreenCaptureNotificationId : kScreenShareNotificationId,
      false /* by_user */);

  std::vector<base::OnceClosure> callbacks;
  std::swap(callbacks,
            is_capture ? capture_stop_callbacks_ : share_stop_callbacks_);
  for (base::OnceClosure& callback : callbacks) {
    if (callback)
      std::move(callback).Run();
  }

  change_source_callback_.Reset();
}

void ScreenSecurityNotificationController::ChangeSource() {
  if (change_source_callback_ && capture_stop_callbacks_.size() == 1)
    change_source_callback_.Run();
}

void ScreenSecurityNotificationController::OnScreenCaptureStart(
    base::RepeatingClosure stop_callback,
    base::RepeatingClosure source_callback,
    const base::string16& screen_capture_status) {
  capture_stop_callbacks_.emplace_back(std::move(stop_callback));
  change_source_callback_ = std::move(source_callback);

  // We do not want to show the screen capture notification and the chromecast
  // casting tray notification at the same time.
  //
  // This suppression technique is currently dependent on the order
  // that OnScreenCaptureStart and OnCastingSessionStartedOrStopped
  // get invoked. OnCastingSessionStartedOrStopped currently gets
  // called first.
  if (is_casting_)
    return;

  CreateNotification(screen_capture_status, true /* is_capture */);
}

void ScreenSecurityNotificationController::OnScreenCaptureStop() {
  StopAllSessions(true /* is_capture */);
}

void ScreenSecurityNotificationController::OnScreenShareStart(
    const base::Closure& stop_callback,
    const base::string16& helper_name) {
  share_stop_callbacks_.emplace_back(std::move(stop_callback));

  base::string16 help_label_text;
  if (!helper_name.empty()) {
    help_label_text = l10n_util::GetStringFUTF16(
        IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED_NAME, helper_name);
  } else {
    help_label_text = l10n_util::GetStringUTF16(
        IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED);
  }

  CreateNotification(help_label_text, false /* is_capture */);
}

void ScreenSecurityNotificationController::OnScreenShareStop() {
  StopAllSessions(false /* is_capture */);
}

void ScreenSecurityNotificationController::OnCastingSessionStartedOrStopped(
    bool started) {
  is_casting_ = started;
}

}  // namespace ash
