// Copyright (c) 2012 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/ui/webui/chromeos/login/reset_screen_handler.h"

#include <string>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/login/help_app_launcher.h"
#include "chrome/browser/chromeos/reset/metrics.h"
#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
#include "chrome/common/pref_names.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager_client.h"
#include "chromeos/dbus/session_manager_client.h"
#include "chromeos/dbus/update_engine_client.h"
#include "content/public/browser/browser_thread.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

const char kJsScreenPath[] = "login.ResetScreen";

// Reset screen id.
const char kResetScreen[] = "reset";

const int kErrorUIStateRollback = 7;

static const char kRollbackFlagFile[] = "/tmp/.enable_rollback_ui";

void CheckRollbackFlagFileExists(bool *file_exists) {
  DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
  *file_exists = base::PathExists(base::FilePath(kRollbackFlagFile));
}

}  // namespace

namespace chromeos {

ResetScreenHandler::ResetScreenHandler()
    : BaseScreenHandler(kJsScreenPath),
      delegate_(NULL),
      show_on_init_(false),
      restart_required_(true),
      reboot_was_requested_(false),
      rollback_available_(false),
      preparing_for_rollback_(false),
      weak_ptr_factory_(this) {
}

ResetScreenHandler::~ResetScreenHandler() {
  if (delegate_)
    delegate_->OnActorDestroyed(this);
  DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
}

void ResetScreenHandler::PrepareToShow() {
}

void ResetScreenHandler::ShowWithParams() {
  int dialog_type;
  if (reboot_was_requested_) {
    dialog_type = rollback_available_ ?
        reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_AND_ROLLBACK :
        reset::DIALOG_SHORTCUT_CONFIRMING_POWERWASH_ONLY;
  } else {
    dialog_type = rollback_available_ ?
      reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_AVAILABLE :
      reset::DIALOG_SHORTCUT_OFFERING_ROLLBACK_UNAVAILABLE;
  }
  UMA_HISTOGRAM_ENUMERATION("Reset.ChromeOS.PowerwashDialogShown",
                            dialog_type,
                            reset::DIALOG_VIEW_TYPE_SIZE);

  base::DictionaryValue reset_screen_params;
  reset_screen_params.SetBoolean("showRestartMsg", restart_required_);
  reset_screen_params.SetBoolean(
      "showRollbackOption", rollback_available_ && !reboot_was_requested_);
  reset_screen_params.SetBoolean(
      "simpleConfirm", reboot_was_requested_ && !rollback_available_);
  reset_screen_params.SetBoolean(
      "rollbackConfirm", reboot_was_requested_ && rollback_available_);

  PrefService* prefs = g_browser_process->local_state();
  prefs->SetBoolean(prefs::kFactoryResetRequested, false);
  prefs->SetBoolean(prefs::kRollbackRequested, false);
  prefs->CommitPendingWrite();
  ShowScreen(kResetScreen, &reset_screen_params);
}

void ResetScreenHandler::Show() {
  if (!page_is_ready()) {
    show_on_init_ = true;
    return;
  }

  ChooseAndApplyShowScenario();
}

void ResetScreenHandler::ChooseAndApplyShowScenario() {
  PrefService* prefs = g_browser_process->local_state();
  restart_required_ = !CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kFirstExecAfterBoot);
  reboot_was_requested_ = false;
  rollback_available_ = false;
  preparing_for_rollback_ = false;
  if (!restart_required_)  // First exec after boot.
    reboot_was_requested_ = prefs->GetBoolean(prefs::kFactoryResetRequested);

  // Check Rollback flag-file.
  scoped_ptr<bool> file_exists(new bool(false));
  base::Closure checkfile_closure = base::Bind(
      &CheckRollbackFlagFileExists,
      base::Unretained(file_exists.get()));
  base::Closure on_check_done = base::Bind(
      &ResetScreenHandler::OnRollbackFlagFileCheckDone,
      weak_ptr_factory_.GetWeakPtr(),
      base::Passed(file_exists.Pass()));
  if (!content::BrowserThread::PostBlockingPoolTaskAndReply(
          FROM_HERE,
          checkfile_closure,
          on_check_done)) {
    LOG(WARNING) << "Failed to check flag file for Rollback reset option";
    on_check_done.Run();
  }
}

void ResetScreenHandler::OnRollbackFlagFileCheckDone(
    scoped_ptr<bool> file_exists) {
  if (!(*file_exists) && !CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kEnableRollbackOption)) {
    rollback_available_ = false;
    ShowWithParams();
  } else if (!restart_required_ && reboot_was_requested_) {
    // First exec after boot.
    PrefService* prefs = g_browser_process->local_state();
    rollback_available_ = prefs->GetBoolean(prefs::kRollbackRequested);
    ShowWithParams();
  } else {
    chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->
        CanRollbackCheck(base::Bind(&ResetScreenHandler::OnRollbackCheck,
        weak_ptr_factory_.GetWeakPtr()));
  }
}

void ResetScreenHandler::Hide() {
  DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
}

void ResetScreenHandler::SetDelegate(Delegate* delegate) {
  delegate_ = delegate;
  if (page_is_ready())
    Initialize();
}

void ResetScreenHandler::DeclareLocalizedValues(
    LocalizedValuesBuilder* builder) {
  builder->Add("resetScreenTitle", IDS_RESET_SCREEN_TITLE);
  builder->Add("resetScreenAccessibleTitle", IDS_RESET_SCREEN_TITLE);
  builder->Add("resetScreenIconTitle",IDS_RESET_SCREEN_ICON_TITLE);
  builder->Add("cancelButton", IDS_CANCEL);

  builder->Add("resetWarningDataDetails",
               IDS_RESET_SCREEN_WARNING_DETAILS_DATA);
  builder->Add("resetRestartMessage", IDS_RESET_SCREEN_RESTART_MSG);
  builder->AddF("resetRollbackOption",
                IDS_RESET_SCREEN_ROLLBACK_OPTION,
                IDS_SHORT_PRODUCT_NAME);
  builder->AddF("resetRevertPromise",
                IDS_RESET_SCREEN_PREPARING_REVERT_PROMISE,
                IDS_SHORT_PRODUCT_NAME);
  builder->AddF("resetRevertSpinnerMessage",
                IDS_RESET_SCREEN_PREPARING_REVERT_SPINNER_MESSAGE,
                IDS_SHORT_PRODUCT_NAME);

  // Different variants of the same UI elements for all dialog cases.
  builder->Add("resetButtonReset", IDS_RESET_SCREEN_RESET);
  builder->Add("resetButtonRelaunch", IDS_RELAUNCH_BUTTON);
  builder->Add("resetButtonPowerwash", IDS_RESET_SCREEN_POWERWASH);

  builder->AddF(
      "resetAndRollbackWarningTextConfirmational",
      IDS_RESET_SCREEN_CONFIRMATION_WARNING_POWERWASH_AND_ROLLBACK_MSG,
      IDS_SHORT_PRODUCT_NAME);
  builder->AddF("resetWarningTextConfirmational",
                IDS_RESET_SCREEN_CONFIRMATION_WARNING_POWERWASH_MSG,
                IDS_SHORT_PRODUCT_NAME);
  builder->AddF("resetWarningTextInitial",
                IDS_RESET_SCREEN_WARNING_MSG,
                IDS_SHORT_PRODUCT_NAME);

  builder->AddF(
      "resetAndRollbackWarningDetailsConfirmational",
      IDS_RESET_SCREEN_CONFIRMATION_WARNING_ROLLBACK_DETAILS,
      IDS_SHORT_PRODUCT_NAME);
  builder->AddF("resetWarningDetailsConfirmational",
                IDS_RESET_SCREEN_CONFIRMATION_WARNING_DETAILS,
                IDS_SHORT_PRODUCT_NAME);
  builder->AddF("resetWarningDetailsInitial",
                IDS_RESET_SCREEN_WARNING_DETAILS,
                IDS_SHORT_PRODUCT_NAME);
}

// Invoked from call to CanRollbackCheck upon completion of the DBus call.
void ResetScreenHandler::OnRollbackCheck(bool can_rollback) {
  VLOG(1) << "Callback from CanRollbackCheck, result " << can_rollback;
  rollback_available_ = can_rollback;
  ShowWithParams();
}

// static
void ResetScreenHandler::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterBooleanPref(prefs::kFactoryResetRequested, false);
  registry->RegisterBooleanPref(prefs::kRollbackRequested, false);
}

void ResetScreenHandler::Initialize() {
  if (!page_is_ready() || !delegate_)
    return;

  if (show_on_init_) {
    Show();
    show_on_init_ = false;
  }
}

void ResetScreenHandler::RegisterMessages() {
  AddCallback("cancelOnReset", &ResetScreenHandler::HandleOnCancel);
  AddCallback("restartOnReset", &ResetScreenHandler::HandleOnRestart);
  AddCallback("powerwashOnReset", &ResetScreenHandler::HandleOnPowerwash);
  AddCallback("resetOnLearnMore", &ResetScreenHandler::HandleOnLearnMore);
}

void ResetScreenHandler::HandleOnCancel() {
  if (preparing_for_rollback_)
    return;
  if (delegate_)
    delegate_->OnExit();
  DBusThreadManager::Get()->GetUpdateEngineClient()->RemoveObserver(this);
}

void ResetScreenHandler::HandleOnRestart(bool should_rollback) {
  PrefService* prefs = g_browser_process->local_state();
  prefs->SetBoolean(prefs::kFactoryResetRequested, true);
  prefs->SetBoolean(prefs::kRollbackRequested, should_rollback);
  prefs->CommitPendingWrite();

  chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
}

void ResetScreenHandler::HandleOnPowerwash(bool rollback_checked) {
  if (rollback_available_ && (rollback_checked || reboot_was_requested_)) {
      preparing_for_rollback_ = true;
      CallJS("updateViewOnRollbackCall");
      DBusThreadManager::Get()->GetUpdateEngineClient()->AddObserver(this);
      chromeos::DBusThreadManager::Get()->GetUpdateEngineClient()->Rollback();
  } else {
    if (rollback_checked && !rollback_available_) {
      NOTREACHED() <<
          "Rollback was checked but not available. Starting powerwash.";
    }
    chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->
        StartDeviceWipe();
  }
}

void ResetScreenHandler::HandleOnLearnMore() {
  if (!help_app_.get())
    help_app_ = new HelpAppLauncher(GetNativeWindow());
  help_app_->ShowHelpTopic(HelpAppLauncher::HELP_POWERWASH);
}

void ResetScreenHandler::UpdateStatusChanged(
    const UpdateEngineClient::Status& status) {
  VLOG(1) << "Update status change to " << status.status;
  if (status.status == UpdateEngineClient::UPDATE_STATUS_ERROR ||
      status.status ==
          UpdateEngineClient::UPDATE_STATUS_REPORTING_ERROR_EVENT) {
    preparing_for_rollback_ = false;
    // Show error screen.
    base::DictionaryValue params;
    params.SetInteger("uiState", kErrorUIStateRollback);
    ShowScreen(OobeUI::kScreenErrorMessage, &params);
  } else if (status.status ==
      UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT) {
    DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart();
  }
}

}  // namespace chromeos
