// 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 "chrome/browser/policy/machine_level_user_cloud_policy_register_watcher.h"

#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/metrics/histogram_macros.h"
#include "base/syslog_logging.h"
#include "chrome/browser/policy/browser_dm_token_storage.h"
#include "chrome/grit/chromium_strings.h"
#include "ui/base/l10n/l10n_util.h"

namespace policy {

using RegisterResult = MachineLevelUserCloudPolicyController::RegisterResult;

const char
    MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName[] =
        "Enterprise.MachineLevelUserCloudPolicyEnrollment.StartupDialog";

MachineLevelUserCloudPolicyRegisterWatcher::
    MachineLevelUserCloudPolicyRegisterWatcher(
        MachineLevelUserCloudPolicyController* controller)
    : controller_(controller) {
  controller_->AddObserver(this);
}
MachineLevelUserCloudPolicyRegisterWatcher::
    ~MachineLevelUserCloudPolicyRegisterWatcher() {
  controller_->RemoveObserver(this);
}

RegisterResult MachineLevelUserCloudPolicyRegisterWatcher::
    WaitUntilCloudPolicyEnrollmentFinished() {
  BrowserDMTokenStorage* token_storage = BrowserDMTokenStorage::Get();

  if (token_storage->RetrieveEnrollmentToken().empty())
    return RegisterResult::kNoEnrollmentNeeded;

  // We are already enrolled successfully.
  if (!token_storage->RetrieveDMToken().empty())
    return RegisterResult::kEnrollmentSuccessBeforeDialogDisplayed;

  EnterpriseStartupDialog::DialogResultCallback callback = base::BindOnce(
      &MachineLevelUserCloudPolicyRegisterWatcher::OnDialogClosed,
      base::Unretained(this));
  if (dialog_creation_callback_)
    dialog_ = std::move(dialog_creation_callback_).Run(std::move(callback));
  else
    dialog_ = EnterpriseStartupDialog::CreateAndShowDialog(std::move(callback));

  visible_start_time_ = base::Time::Now();

  if (register_result_) {
    // |register_result_| has been set only if the enrollment has finished.
    // And it must be failed if it's finished without a DM token which is
    // checked above. Show the error message directly.
    DCHECK(!register_result_.value());

    if (!token_storage->ShouldDisplayErrorMessageOnFailure())
      return RegisterResult::kEnrollmentFailedSilentlyBeforeDialogDisplayed;

    DisplayErrorMessage();
  } else {
    // Display the loading dialog and wait for the enrollment process.
    dialog_->DisplayLaunchingInformationWithThrobber(l10n_util::GetStringUTF16(
        IDS_ENTERPRISE_STARTUP_CLOUD_POLICY_ENROLLMENT_TOOLTIP));
  }
  RecordEnrollmentStartDialog(EnrollmentStartupDialog::kShown);
  run_loop_.Run();
  if (register_result_.value_or(false))
    return RegisterResult::kEnrollmentSuccess;

  if (!token_storage->ShouldDisplayErrorMessageOnFailure() &&
      register_result_) {
    SYSLOG(ERROR) << "Machine level user cloud policy enrollment has failed.";
    return RegisterResult::kEnrollmentFailedSilently;
  }

  SYSLOG(ERROR) << "Can not start Chrome as machine level user cloud policy "
                   "enrollment has failed. Please double check network "
                   "connection and the status of enrollment token then open "
                   "Chrome again.";

  if (is_restart_needed_)
    return RegisterResult::kRestartDueToFailure;
  return RegisterResult::kQuitDueToFailure;
}

bool MachineLevelUserCloudPolicyRegisterWatcher::IsDialogShowing() {
  return (dialog_ && dialog_->IsShowing()) || run_loop_.running();
}

void MachineLevelUserCloudPolicyRegisterWatcher::
    SetDialogCreationCallbackForTesting(DialogCreationCallback callback) {
  dialog_creation_callback_ = std::move(callback);
}

// static
void MachineLevelUserCloudPolicyRegisterWatcher::RecordEnrollmentStartDialog(
    EnrollmentStartupDialog dialog_startup) {
  UMA_HISTOGRAM_ENUMERATION(kStartupDialogHistogramName, dialog_startup);
}

void MachineLevelUserCloudPolicyRegisterWatcher::OnPolicyRegisterFinished(
    bool succeeded) {
  register_result_ = succeeded;

  // If dialog still exists, dismiss the dialog for a success enrollment or
  // show the error message. If dialog has been closed before enrollment
  // finished, Chrome should already be in the shutdown process.
  if (dialog_ && dialog_->IsShowing()) {
    if (register_result_.value() ||
        !BrowserDMTokenStorage::Get()->ShouldDisplayErrorMessageOnFailure()) {
      dialog_.reset();
    } else {
      DisplayErrorMessage();
    }
  }
}

void MachineLevelUserCloudPolicyRegisterWatcher::OnDialogClosed(
    bool is_accepted,
    bool can_show_browser_window) {
  if (can_show_browser_window) {
    // Chrome startup can continue normally.
    if (register_result_.value()) {
      RecordEnrollmentStartDialog(EnrollmentStartupDialog::kClosedSuccess);
    } else {
      RecordEnrollmentStartDialog(
          EnrollmentStartupDialog::kClosedFailAndIgnore);
    }
  } else if (is_accepted) {
    // User chose to restart chrome and try re-enrolling.
    RecordEnrollmentStartDialog(EnrollmentStartupDialog::kClosedRelaunch);
  } else if (register_result_.has_value()) {
    // User closed the dialog after seeing a message that enrollment failed.
    RecordEnrollmentStartDialog(EnrollmentStartupDialog::kClosedFail);
  } else {
    // User closed the dialog after waiting too long with no result.
    RecordEnrollmentStartDialog(EnrollmentStartupDialog::kClosedAbort);
  }

  base::TimeDelta visible_time = base::Time::Now() - visible_start_time_;
  UMA_HISTOGRAM_TIMES(
      "Enterprise.MachineLevelUserCloudPolicyEnrollment.StartupDialogTime",
      visible_time);

  // User confirm the dialog to relaunch Chrome to retry the register.
  is_restart_needed_ = is_accepted;

  // Resume the launch process once the dialog is closed.
  run_loop_.Quit();
}

void MachineLevelUserCloudPolicyRegisterWatcher::DisplayErrorMessage() {
  dialog_->DisplayErrorMessage(
      l10n_util::GetStringUTF16(
          IDS_ENTERPRISE_STARTUP_CLOUD_POLICY_ENROLLMENT_ERROR),
      l10n_util::GetStringUTF16(IDS_ENTERPRISE_STARTUP_RELAUNCH_BUTTON));
}

}  // namespace policy
