// 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/message_center/ash_message_center_lock_screen_controller.h"

#include "ash/login/ui/lock_screen.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/ash_pref_names.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/status_area_widget.h"
#include "ash/system/toast/toast_data.h"
#include "ash/system/toast/toast_manager.h"
#include "ash/system/unified/unified_system_tray.h"
#include "base/strings/utf_string_conversions.h"
#include "components/prefs/pref_service.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/widget/widget.h"

namespace ash {

// static private
base::Optional<AshMessageCenterLockScreenController::Mode>
    AshMessageCenterLockScreenController::overridden_mode_for_testing_;

// static
bool AshMessageCenterLockScreenController::IsEnabled() {
  auto mode = GetMode();
  bool is_showing = (mode == Mode::SHOW || mode == Mode::HIDE_SENSITIVE);
  // If |isAllowed()| is false, must return false;
  DCHECK(!is_showing || IsAllowed());
  return is_showing;
}

// static
bool AshMessageCenterLockScreenController::IsAllowed() {
  return GetMode() != Mode::PROHIBITED;
}

// static, private
AshMessageCenterLockScreenController::Mode
AshMessageCenterLockScreenController::GetMode() {
  if (overridden_mode_for_testing_.has_value())
    return *overridden_mode_for_testing_;

  if (!features::IsLockScreenNotificationsEnabled())
    return Mode::PROHIBITED;

  // User prefs may be null in some tests.
  PrefService* user_prefs =
      Shell::Get()->session_controller()->GetLastActiveUserPrefService();
  if (!user_prefs)
    return Mode::PROHIBITED;

  const std::string& mode =
      user_prefs->GetString(prefs::kMessageCenterLockScreenMode);
  if (mode == prefs::kMessageCenterLockScreenModeShow)
    return Mode::SHOW;
  if (mode == prefs::kMessageCenterLockScreenModeHideSensitive &&
      features::IsLockScreenHideSensitiveNotificationsSupported())
    return Mode::HIDE_SENSITIVE;

  return Mode::HIDE;
}

// static, only for testing
void AshMessageCenterLockScreenController::OverrideModeForTest(
    base::Optional<AshMessageCenterLockScreenController::Mode> new_mode) {
  overridden_mode_for_testing_ = new_mode;
}

namespace {
const char kToastId[] = "ash-lock-screen-manager";
}  // anonymous namespace

AshMessageCenterLockScreenController::AshMessageCenterLockScreenController()
    : locked_(Shell::Get()->session_controller()->IsScreenLocked()) {}

AshMessageCenterLockScreenController::~AshMessageCenterLockScreenController() {
  // Invokes the cancel task if any.
  if (cancel_task_)
    std::move(cancel_task_).Run();
}

void AshMessageCenterLockScreenController::DismissLockScreenThenExecute(
    base::OnceClosure pending_callback,
    base::OnceClosure cancel_callback,
    int message_id) {
  if (locked_) {
    // Invokes the previous cancel task if any.
    if (cancel_task_)
      std::move(cancel_task_).Run();

    // Stores the new pending/cancel tasks.
    pending_task_ = std::move(pending_callback);
    cancel_task_ = std::move(cancel_callback);

    EncourageUserToUnlock(message_id);
  } else {
    DCHECK(pending_task_.is_null());
    DCHECK(cancel_task_.is_null());
    if (pending_callback)
      std::move(pending_callback).Run();
  }
}

bool AshMessageCenterLockScreenController::IsScreenLocked() const {
  return locked_;
}

void AshMessageCenterLockScreenController::EncourageUserToUnlock(
    int message_id) {
  DCHECK(locked_);

  DCHECK(LockScreen::Get());
  DCHECK(LockScreen::Get()->widget());
  auto* unified_system_tray =
      Shelf::ForWindow(LockScreen::Get()->widget()->GetNativeWindow())
          ->GetStatusAreaWidget()
          ->unified_system_tray();
  if (unified_system_tray) {
    // Lockscreen notification works only with the unified system tray.
    unified_system_tray->CloseBubble();
  }

  base::string16 message;
  if (message_id != -1) {
    message = l10n_util::GetStringUTF16(message_id);
  } else {
    message =
        (Shell::Get()->session_controller()->NumberOfLoggedInUsers() == 1 ||
         active_account_id_.empty())
            ? l10n_util::GetStringUTF16(
                  IDS_ASH_MESSAGE_CENTER_UNLOCK_TO_PERFORM_ACTION)
            : l10n_util::GetStringFUTF16(
                  IDS_ASH_MESSAGE_CENTER_UNLOCK_TO_PERFORM_ACTION_WITH_USER_ID,
                  base::UTF8ToUTF16(active_account_id_.GetUserEmail()));
  }

  // TODO(yoshiki): Update UI after the UX finalizes.
  Shell::Get()->toast_manager()->Show(
      ToastData(kToastId, message, ToastData::kInfiniteDuration, base::nullopt,
                /*visible_on_lock_screen=*/true));
}

void AshMessageCenterLockScreenController::OnLockStateChanged(bool locked) {
  if (locked_ == locked)
    return;

  locked_ = locked;

  if (!locked) {
    Shell::Get()->toast_manager()->Cancel(kToastId);

    // Invokes the pending task and resets the cancel task.
    if (pending_task_)
      std::move(pending_task_).Run();
    std::move(cancel_task_).Reset();
  } else {
    DCHECK(pending_task_.is_null());
    DCHECK(cancel_task_.is_null());
  }
}

void AshMessageCenterLockScreenController::OnActiveUserSessionChanged(
    const AccountId& account_id) {
  if (active_account_id_ == account_id)
    return;

  active_account_id_ = account_id;

  if (locked_) {
    // Cancels the current callbacks, if the user switches the active account
    // on the lock screen.
    DCHECK(Shell::Get());
    DCHECK(Shell::Get()->toast_manager());
    Shell::Get()->toast_manager()->Cancel(kToastId);

    std::move(pending_task_).Reset();
    if (cancel_task_)
      std::move(cancel_task_).Run();
  }
}

}  // namespace ash
