// 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/assistant/assistant_notification_controller.h"

#include <memory>
#include <utility>

#include "ash/assistant/assistant_controller.h"
#include "ash/assistant/util/deep_link_util.h"
#include "ash/new_window_controller.h"
#include "ash/public/cpp/notification_utils.h"
#include "ash/public/cpp/vector_icons/vector_icons.h"
#include "ash/public/interfaces/voice_interaction_controller.mojom.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/voice_interaction/voice_interaction_controller.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/public/cpp/notification.h"
#include "url/gurl.h"

namespace ash {

namespace {

constexpr char kNotifierId[] = "assistant";

// Helpers ---------------------------------------------------------------------

std::unique_ptr<message_center::Notification> CreateSystemNotification(
    const message_center::NotifierId& notifier_id,
    const chromeos::assistant::mojom::AssistantNotification* notification) {
  const base::string16 title = base::UTF8ToUTF16(notification->title);
  const base::string16 message = base::UTF8ToUTF16(notification->message);
  const base::string16 display_source =
      l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_NOTIFICATION_DISPLAY_SOURCE);

  message_center::RichNotificationData data;
  for (const auto& button : notification->buttons) {
    data.buttons.push_back(
        message_center::ButtonInfo(base::UTF8ToUTF16(button->label)));
  }

  std::unique_ptr<message_center::Notification> system_notification =
      ash::CreateSystemNotification(
          message_center::NOTIFICATION_TYPE_SIMPLE, notification->client_id,
          title, message, display_source, GURL(), notifier_id, data,
          /*delegate=*/nullptr, kNotificationAssistantIcon,
          message_center::SystemNotificationWarningLevel::NORMAL);

  if (notification->is_high_priority)
    system_notification->set_priority(message_center::HIGH_PRIORITY);

  return system_notification;
}

message_center::NotifierId GetNotifierId() {
  return message_center::NotifierId(
      message_center::NotifierType::SYSTEM_COMPONENT, kNotifierId);
}

bool IsSystemNotification(
    const chromeos::assistant::mojom::AssistantNotification* notification) {
  using chromeos::assistant::mojom::AssistantNotificationType;
  return notification->type == AssistantNotificationType::kPreferInAssistant ||
         notification->type == AssistantNotificationType::kSystem;
}

bool IsValidActionUrl(const GURL& action_url) {
  return action_url.is_valid() && (action_url.SchemeIsHTTPOrHTTPS() ||
                                   assistant::util::IsDeepLinkUrl(action_url));
}

}  // namespace

// AssistantNotificationController ---------------------------------------------

AssistantNotificationController::AssistantNotificationController(
    AssistantController* assistant_controller)
    : assistant_controller_(assistant_controller),
      binding_(this),
      notifier_id_(GetNotifierId()) {
  AddModelObserver(this);
  assistant_controller_->AddObserver(this);
  message_center::MessageCenter::Get()->AddObserver(this);
}

AssistantNotificationController::~AssistantNotificationController() {
  message_center::MessageCenter::Get()->RemoveObserver(this);
  assistant_controller_->RemoveObserver(this);
  RemoveModelObserver(this);
}

void AssistantNotificationController::BindRequest(
    mojom::AssistantNotificationControllerRequest request) {
  binding_.Bind(std::move(request));
}

void AssistantNotificationController::AddModelObserver(
    AssistantNotificationModelObserver* observer) {
  model_.AddObserver(observer);
}

void AssistantNotificationController::RemoveModelObserver(
    AssistantNotificationModelObserver* observer) {
  model_.RemoveObserver(observer);
}

void AssistantNotificationController::SetAssistant(
    chromeos::assistant::mojom::Assistant* assistant) {
  assistant_ = assistant;
}

// AssistantControllerObserver -------------------------------------------------

void AssistantNotificationController::OnAssistantControllerConstructed() {
  assistant_controller_->ui_controller()->AddModelObserver(this);
}

void AssistantNotificationController::OnAssistantControllerDestroying() {
  assistant_controller_->ui_controller()->RemoveModelObserver(this);
}

// AssistantUiModelObserver ----------------------------------------------------

void AssistantNotificationController::OnUiVisibilityChanged(
    AssistantVisibility new_visibility,
    AssistantVisibility old_visibility,
    base::Optional<AssistantEntryPoint> entry_point,
    base::Optional<AssistantExitPoint> exit_point) {
  switch (new_visibility) {
    case AssistantVisibility::kVisible:
      // When the Assistant UI becomes visible we convert any notifications of
      // type |kPreferInAssistant| to type |kInAssistant|. This will cause them
      // to be removed from the Message Center (if they had previously been
      // added) and to finish out their lifetimes as in-Assistant notifications.
      for (const auto* notification : model_.GetNotificationsByType(
               AssistantNotificationType::kPreferInAssistant)) {
        auto update = notification->Clone();
        update->type = AssistantNotificationType::kInAssistant;
        model_.AddOrUpdateNotification(std::move(update));
      }
      break;
    case AssistantVisibility::kHidden:
    case AssistantVisibility::kClosed:
      // When the Assistant UI is no longer visible to the user we remove any
      // notifications of type |kInAssistant| as this type of notification does
      // not outlive the Assistant view hierarchy.
      if (old_visibility == AssistantVisibility::kVisible) {
        for (const auto* notification : model_.GetNotificationsByType(
                 AssistantNotificationType::kInAssistant)) {
          model_.RemoveNotificationById(notification->client_id,
                                        /*from_server=*/false);
        }
      }
      break;
  }
}

// mojom::AssistantNotificationController --------------------------------------

void AssistantNotificationController::AddOrUpdateNotification(
    AssistantNotificationPtr notification) {
  const AssistantVisibility visibility =
      assistant_controller_->ui_controller()->model()->visibility();

  // If Assistant UI is visible and |notification| is of type
  // |kPreferInAssistant|, we convert it to a notification of type
  // |kInAssistant|. This will cause the notification to be removed from the
  // Message Center (if it had previously been added) and it will finish out its
  // lifetime as an in-Assistant notification.
  if (visibility == AssistantVisibility::kVisible &&
      notification->type == AssistantNotificationType::kPreferInAssistant) {
    notification->type = AssistantNotificationType::kInAssistant;
  }

  model_.AddOrUpdateNotification(std::move(notification));
}

void AssistantNotificationController::RemoveNotificationById(
    const std::string& id,
    bool from_server) {
  model_.RemoveNotificationById(id, from_server);
}

void AssistantNotificationController::RemoveNotificationByGroupingKey(
    const std::string& grouping_key,
    bool from_server) {
  model_.RemoveNotificationsByGroupingKey(grouping_key, from_server);
}

void AssistantNotificationController::RemoveAllNotifications(bool from_server) {
  model_.RemoveAllNotifications(from_server);
}

// AssistantNotificationModelObserver ------------------------------------------

void AssistantNotificationController::OnNotificationAdded(
    const AssistantNotification* notification) {
  // Do not show system notifications if the setting is disabled.
  if (!Shell::Get()->voice_interaction_controller()->notification_enabled())
    return;

  // We only show system notifications in the Message Center.
  if (!IsSystemNotification(notification))
    return;

  message_center::MessageCenter::Get()->AddNotification(
      CreateSystemNotification(notifier_id_, notification));
}

void AssistantNotificationController::OnNotificationUpdated(
    const AssistantNotification* notification) {
  // Do not show system notifications if the setting is disabled.
  if (!Shell::Get()->voice_interaction_controller()->notification_enabled())
    return;

  // If the notification that was updated is *not* a system notification, we
  // need to ensure that it is removed from the Message Center (given that it
  // may have been a system notification prior to update).
  if (!IsSystemNotification(notification)) {
    message_center::MessageCenter::Get()->RemoveNotification(
        notification->client_id, /*by_user=*/false);
    return;
  }

  message_center::MessageCenter::Get()->UpdateNotification(
      notification->client_id,
      CreateSystemNotification(notifier_id_, notification));
}

void AssistantNotificationController::OnNotificationRemoved(
    const AssistantNotification* notification,
    bool from_server) {
  // Remove the notification from the message center.
  message_center::MessageCenter::Get()->RemoveNotification(
      notification->client_id, /*by_user=*/false);

  // Dismiss the notification on the server to sync across devices.
  if (!from_server)
    assistant_->DismissNotification(notification->Clone());
}

void AssistantNotificationController::OnAllNotificationsRemoved(
    bool from_server) {
  message_center::MessageCenter::Get()->RemoveNotificationsForNotifierId(
      notifier_id_);
}

// message_center::MessageCenterObserver ---------------------------------------

void AssistantNotificationController::OnNotificationClicked(
    const std::string& id,
    const base::Optional<int>& button_index,
    const base::Optional<base::string16>& reply) {
  const AssistantNotification* notification = model_.GetNotificationById(id);
  if (!notification)
    return;

  const auto& action_url =
      button_index.has_value()
          ? notification->buttons[button_index.value()]->action_url
          : notification->action_url;

  // Open the action url if it is valid.
  if (IsValidActionUrl(action_url)) {
    assistant_controller_->OpenUrl(action_url);
    model_.RemoveNotificationById(id, /*from_server=*/false);
    return;
  }

  // Otherwise, we retrieve the notification payload from the server using the
  // following indexing scheme:
  //
  // Index:  |    [0]    |   [1]    |   [2]    | ...
  // -------------------------------------------------
  // Action: | Top Level | Button 1 | Button 2 | ...
  const int action_index = button_index.value_or(-1) + 1;
  assistant_->RetrieveNotification(notification->Clone(), action_index);
}

void AssistantNotificationController::OnNotificationRemoved(
    const std::string& notification_id,
    bool by_user) {
  // If the notification that was removed is a system notification, we need to
  // update our notification model. If it is *not* a system notification, then
  // the notification was removed from the Message Center due to a change of
  // |type| so it should be retained in the model.
  const auto* notification = model_.GetNotificationById(notification_id);
  if (notification && IsSystemNotification(notification))
    model_.RemoveNotificationById(notification_id, /*from_server=*/false);
}

}  // namespace ash
