// 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/chromeos/login/demo_mode/demo_setup_controller.h"

#include <utility>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_resources.h"
#include "chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h"
#include "chrome/browser/chromeos/login/startup_utils.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
#include "chrome/browser/chromeos/policy/enrollment_config.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/settings/install_attributes.h"
#include "chromeos/system/statistics_provider.h"
#include "components/arc/arc_util.h"
#include "components/policy/core/common/cloud/cloud_policy_constants.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "ui/base/l10n/l10n_util.h"

namespace chromeos {

namespace {

using ErrorCode = DemoSetupController::DemoSetupError::ErrorCode;
using RecoveryMethod = DemoSetupController::DemoSetupError::RecoveryMethod;

constexpr char kDemoRequisition[] = "cros-demo-mode";
constexpr char kOfflineDevicePolicyFileName[] = "device_policy";
constexpr char kOfflineDeviceLocalAccountPolicyFileName[] =
    "local_account_policy";

// The policy blob data for offline demo-mode is embedded into the filesystem.
// TODO(mukai, agawronska): fix this when switching to dm-verity image.
constexpr const base::FilePath::CharType kOfflineDemoModeDir[] =
    FILE_PATH_LITERAL("/usr/share/demo_mode_resources/policy");

bool CheckOfflinePolicyFilesExist(const base::FilePath& policy_dir,
                                  std::string* message) {
  base::FilePath device_policy_path =
      policy_dir.AppendASCII(kOfflineDevicePolicyFileName);
  if (!base::PathExists(device_policy_path)) {
    *message = base::StringPrintf("Path %s does not exist",
                                  device_policy_path.AsUTF8Unsafe().c_str());
    return false;
  }
  base::FilePath local_account_policy_path =
      policy_dir.AppendASCII(kOfflineDeviceLocalAccountPolicyFileName);
  if (!base::PathExists(local_account_policy_path)) {
    *message =
        base::StringPrintf("Path %s does not exist",
                           local_account_policy_path.AsUTF8Unsafe().c_str());
    return false;
  }

  return true;
}

// Get the DeviceLocalAccountPolicyStore for the account_id.
policy::CloudPolicyStore* GetDeviceLocalAccountPolicyStore(
    const std::string& account_id) {
  policy::BrowserPolicyConnectorChromeOS* connector =
      g_browser_process->platform_part()->browser_policy_connector_chromeos();
  if (!connector)
    return nullptr;

  policy::DeviceLocalAccountPolicyService* local_account_service =
      connector->GetDeviceLocalAccountPolicyService();
  if (!local_account_service)
    return nullptr;

  const std::string user_id = policy::GenerateDeviceLocalAccountUserId(
      account_id, policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
  policy::DeviceLocalAccountPolicyBroker* broker =
      local_account_service->GetBrokerForUser(user_id);
  if (!broker)
    return nullptr;

  return broker->core()->store();
}

// A utility function of base::ReadFileToString which returns an optional
// string.
// TODO(mukai): move this to base/files.
base::Optional<std::string> ReadFileToOptionalString(
    const base::FilePath& file_path) {
  std::string content;
  base::Optional<std::string> result;
  if (base::ReadFileToString(file_path, &content))
    result = std::move(content);
  return result;
}

// Returns whether online FRE check is required.
bool IsOnlineFreCheckRequired() {
  AutoEnrollmentController::FRERequirement fre_requirement =
      AutoEnrollmentController::GetFRERequirement();
  bool enrollment_check_required =
      fre_requirement !=
          AutoEnrollmentController::FRERequirement::kExplicitlyNotRequired &&
      fre_requirement !=
          AutoEnrollmentController::FRERequirement::kNotRequired &&
      AutoEnrollmentController::IsFREEnabled();

  if (!enrollment_check_required)
    return false;

  std::string block_dev_mode_value;
  system::StatisticsProvider* provider =
      system::StatisticsProvider::GetInstance();
  provider->GetMachineStatistic(system::kBlockDevModeKey,
                                &block_dev_mode_value);

  return block_dev_mode_value == "1";
}

DemoSetupController::DemoSetupError CreateFromClientStatus(
    policy::DeviceManagementStatus status,
    const std::string& debug_message) {
  switch (status) {
    case policy::DM_STATUS_SUCCESS:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kUnexpectedError, RecoveryMethod::kUnknown, debug_message);
    case policy::DM_STATUS_REQUEST_INVALID:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kInvalidRequest, RecoveryMethod::kUnknown, debug_message);
    case policy::DM_STATUS_REQUEST_FAILED:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kRequestNetworkError, RecoveryMethod::kCheckNetwork,
          debug_message);
    case policy::DM_STATUS_TEMPORARY_UNAVAILABLE:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kTemporaryUnavailable, RecoveryMethod::kRetry,
          debug_message);
    case policy::DM_STATUS_HTTP_STATUS_ERROR:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kResponseError, RecoveryMethod::kUnknown, debug_message);
    case policy::DM_STATUS_RESPONSE_DECODING_ERROR:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kResponseDecodingError, RecoveryMethod::kUnknown,
          debug_message);
    case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
    case policy::DM_STATUS_SERVICE_CONSUMER_ACCOUNT_WITH_PACKAGED_LICENSE:
    case policy::DM_STATUS_SERVICE_ACTIVATION_PENDING:
      return DemoSetupController::DemoSetupError(ErrorCode::kDemoAccountError,
                                                 RecoveryMethod::kUnknown,
                                                 debug_message);
    case policy::DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kDeviceNotFound, RecoveryMethod::kUnknown, debug_message);
    case policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kInvalidDMToken, RecoveryMethod::kUnknown, debug_message);
    case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kInvalidSerialNumber, RecoveryMethod::kUnknown,
          debug_message);
    case policy::DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kDeviceIdError, RecoveryMethod::kUnknown, debug_message);
    case policy::DM_STATUS_SERVICE_MISSING_LICENSES:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kLicenseError, RecoveryMethod::kUnknown, debug_message);
    case policy::DM_STATUS_SERVICE_DEPROVISIONED:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kDeviceDeprovisioned, RecoveryMethod::kUnknown,
          debug_message);
    case policy::DM_STATUS_SERVICE_DOMAIN_MISMATCH:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kDomainMismatch, RecoveryMethod::kUnknown, debug_message);
    case policy::DM_STATUS_CANNOT_SIGN_REQUEST:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kSigningError, RecoveryMethod::kPowerwash, debug_message);
    case policy::DM_STATUS_SERVICE_POLICY_NOT_FOUND:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kPolicyNotFound, RecoveryMethod::kUnknown, debug_message);
    case policy::DM_STATUS_SERVICE_ARC_DISABLED:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kArcError, RecoveryMethod::kUnknown, debug_message);
  }
  NOTREACHED() << "Demo mode setup received unsupported client status";
  return DemoSetupController::DemoSetupError(
      ErrorCode::kUnexpectedError, RecoveryMethod::kUnknown, debug_message);
}

DemoSetupController::DemoSetupError CreateFromLockStatus(
    InstallAttributes::LockResult status,
    const std::string& debug_message) {
  switch (status) {
    case InstallAttributes::LOCK_SUCCESS:
    case InstallAttributes::LOCK_NOT_READY:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kUnexpectedError, RecoveryMethod::kUnknown, debug_message);
    case InstallAttributes::LOCK_TIMEOUT:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kLockTimeout, RecoveryMethod::kReboot, debug_message);
    case InstallAttributes::LOCK_BACKEND_INVALID:
    case InstallAttributes::LOCK_SET_ERROR:
    case InstallAttributes::LOCK_FINALIZE_ERROR:
    case InstallAttributes::LOCK_READBACK_ERROR:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kLockError, RecoveryMethod::kPowerwash, debug_message);
    case InstallAttributes::LOCK_ALREADY_LOCKED:
    case InstallAttributes::LOCK_WRONG_DOMAIN:
    case InstallAttributes::LOCK_WRONG_MODE:
      return DemoSetupController::DemoSetupError(
          ErrorCode::kAlreadyLocked, RecoveryMethod::kPowerwash, debug_message);
  }
  NOTREACHED() << "Demo mode setup received unsupported lock status";
  return DemoSetupController::DemoSetupError(
      ErrorCode::kUnexpectedError, RecoveryMethod::kUnknown, debug_message);
}

}  //  namespace

// static
constexpr char DemoSetupController::kDemoModeDomain[];

// static
DemoSetupController::DemoSetupError
DemoSetupController::DemoSetupError::CreateFromEnrollmentStatus(
    const policy::EnrollmentStatus& status) {
  const std::string debug_message = base::StringPrintf(
      "EnrollmentError: (status: %d, client_status: %d, store_status: %d, "
      "validation_status: %d, lock_status: %d)",
      status.status(), status.client_status(), status.store_status(),
      status.validation_status(), status.lock_status());

  switch (status.status()) {
    case policy::EnrollmentStatus::SUCCESS:
      return DemoSetupError(ErrorCode::kUnexpectedError,
                            RecoveryMethod::kUnknown, debug_message);
    case policy::EnrollmentStatus::NO_STATE_KEYS:
      return DemoSetupError(ErrorCode::kNoStateKeys, RecoveryMethod::kReboot,
                            debug_message);
    case policy::EnrollmentStatus::REGISTRATION_FAILED:
      return CreateFromClientStatus(status.client_status(), debug_message);
    case policy::EnrollmentStatus::ROBOT_AUTH_FETCH_FAILED:
    case policy::EnrollmentStatus::ROBOT_REFRESH_FETCH_FAILED:
      return DemoSetupError(ErrorCode::kRobotFetchError,
                            RecoveryMethod::kCheckNetwork, debug_message);
    case policy::EnrollmentStatus::ROBOT_REFRESH_STORE_FAILED:
      return DemoSetupError(ErrorCode::kRobotStoreError,
                            RecoveryMethod::kReboot, debug_message);
    case policy::EnrollmentStatus::REGISTRATION_BAD_MODE:
      return DemoSetupError(ErrorCode::kBadMode, RecoveryMethod::kRetry,
                            debug_message);
    case policy::EnrollmentStatus::REGISTRATION_CERT_FETCH_FAILED:
      return DemoSetupError(ErrorCode::kCertFetchError, RecoveryMethod::kRetry,
                            debug_message);
    case policy::EnrollmentStatus::POLICY_FETCH_FAILED:
      return DemoSetupError(ErrorCode::kPolicyFetchError,
                            RecoveryMethod::kRetry, debug_message);
    case policy::EnrollmentStatus::VALIDATION_FAILED:
      return DemoSetupError(ErrorCode::kPolicyValidationError,
                            RecoveryMethod::kRetry, debug_message);
    case policy::EnrollmentStatus::LOCK_ERROR:
      return CreateFromLockStatus(status.lock_status(), debug_message);
    case policy::EnrollmentStatus::STORE_ERROR:
      return DemoSetupError(ErrorCode::kOnlineStoreError,
                            RecoveryMethod::kRetry, debug_message);
    case policy::EnrollmentStatus::ATTRIBUTE_UPDATE_FAILED:
      return DemoSetupError(ErrorCode::kUnexpectedError,
                            RecoveryMethod::kUnknown, debug_message);
    case policy::EnrollmentStatus::NO_MACHINE_IDENTIFICATION:
      return DemoSetupError(ErrorCode::kMachineIdentificationError,
                            RecoveryMethod::kUnknown, debug_message);
    case policy::EnrollmentStatus::ACTIVE_DIRECTORY_POLICY_FETCH_FAILED:
      return DemoSetupError(ErrorCode::kUnexpectedError,
                            RecoveryMethod::kReboot, debug_message);
    case policy::EnrollmentStatus::DM_TOKEN_STORE_FAILED:
      return DemoSetupError(ErrorCode::kDMTokenStoreError,
                            RecoveryMethod::kUnknown, debug_message);
    case policy::EnrollmentStatus::LICENSE_REQUEST_FAILED:
      return DemoSetupError(ErrorCode::kLicenseError, RecoveryMethod::kUnknown,
                            debug_message);
    case policy::EnrollmentStatus::OFFLINE_POLICY_LOAD_FAILED:
    case policy::EnrollmentStatus::OFFLINE_POLICY_DECODING_FAILED:
      return DemoSetupError(ErrorCode::kOfflinePolicyError,
                            RecoveryMethod::kOnlineOnly, debug_message);
  }
  NOTREACHED() << "Demo mode setup received unsupported enrollment status";
  return DemoSetupError(ErrorCode::kUnexpectedError, RecoveryMethod::kUnknown,
                        debug_message);
}

// static
DemoSetupController::DemoSetupError
DemoSetupController::DemoSetupError::CreateFromOtherEnrollmentError(
    EnterpriseEnrollmentHelper::OtherError error) {
  const std::string debug_message =
      base::StringPrintf("Other error: %d", error);
  switch (error) {
    case EnterpriseEnrollmentHelper::OTHER_ERROR_DOMAIN_MISMATCH:
      return DemoSetupError(ErrorCode::kAlreadyLocked,
                            RecoveryMethod::kPowerwash, debug_message);
    case EnterpriseEnrollmentHelper::OTHER_ERROR_FATAL:
      return DemoSetupError(ErrorCode::kUnexpectedError,
                            RecoveryMethod::kUnknown, debug_message);
  }
  NOTREACHED() << "Demo mode setup received unsupported enrollment error";
  return DemoSetupError(ErrorCode::kUnexpectedError, RecoveryMethod::kUnknown,
                        debug_message);
}

// static
DemoSetupController::DemoSetupError
DemoSetupController::DemoSetupError::CreateFromComponentError(
    component_updater::CrOSComponentManager::Error error) {
  const std::string debug_message =
      "Failed to load demo resources CrOS component with error: " +
      std::to_string(static_cast<int>(error));
  return DemoSetupError(ErrorCode::kOnlineComponentError,
                        RecoveryMethod::kCheckNetwork, debug_message);
}

DemoSetupController::DemoSetupError::DemoSetupError(
    DemoSetupError::ErrorCode error_code,
    DemoSetupError::RecoveryMethod recovery_method)
    : error_code_(error_code), recovery_method_(recovery_method) {}

DemoSetupController::DemoSetupError::DemoSetupError(
    DemoSetupError::ErrorCode error_code,
    DemoSetupError::RecoveryMethod recovery_method,
    const std::string& debug_message)
    : error_code_(error_code),
      recovery_method_(recovery_method),
      debug_message_(debug_message) {}

DemoSetupController::DemoSetupError::~DemoSetupError() = default;

base::string16 DemoSetupController::DemoSetupError::GetLocalizedErrorMessage()
    const {
  switch (error_code_) {
    case ErrorCode::kNoOfflineResources:
      return l10n_util::GetStringUTF16(
          IDS_DEMO_SETUP_NO_OFFLINE_RESOURCES_ERROR);
    case ErrorCode::kOfflinePolicyError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_OFFLINE_POLICY_ERROR);
    case ErrorCode::kOfflinePolicyStoreError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_OFFLINE_STORE_ERROR);
    case ErrorCode::kOnlineFRECheckRequired:
      return l10n_util::GetStringUTF16(
          IDS_DEMO_SETUP_OFFLINE_UNAVAILABLE_ERROR);
    case ErrorCode::kOnlineComponentError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_COMPONENT_ERROR);
    case ErrorCode::kNoStateKeys:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_NO_STATE_KEYS_ERROR);
    case ErrorCode::kInvalidRequest:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_INVALID_REQUEST_ERROR);
    case ErrorCode::kRequestNetworkError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_NETWORK_ERROR);
    case ErrorCode::kTemporaryUnavailable:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_TEMPORARY_ERROR);
    case ErrorCode::kResponseError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_RESPONSE_ERROR);
    case ErrorCode::kResponseDecodingError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_RESPONSE_DECODING_ERROR);
    case ErrorCode::kDemoAccountError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_ACCOUNT_ERROR);
    case ErrorCode::kDeviceNotFound:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_DEVICE_NOT_FOUND_ERROR);
    case ErrorCode::kInvalidDMToken:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_INVALID_DM_TOKEN_ERROR);
    case ErrorCode::kInvalidSerialNumber:
      return l10n_util::GetStringUTF16(
          IDS_DEMO_SETUP_INVALID_SERIAL_NUMBER_ERROR);
    case ErrorCode::kDeviceIdError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_DEVICE_ID_ERROR);
    case ErrorCode::kLicenseError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_LICENSE_ERROR);
    case ErrorCode::kDeviceDeprovisioned:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_DEPROVISIONED_ERROR);
    case ErrorCode::kDomainMismatch:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_DOMAIN_MISMATCH_ERROR);
    case ErrorCode::kSigningError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_SIGNING_ERROR);
    case ErrorCode::kPolicyNotFound:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_POLICY_NOT_FOUND_ERROR);
    case ErrorCode::kArcError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_ARC_ERROR);
    case ErrorCode::kRobotFetchError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_ROBOT_ERROR);
    case ErrorCode::kRobotStoreError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_ROBOT_STORE_ERROR);
    case ErrorCode::kBadMode:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_BAD_MODE_ERROR);
    case ErrorCode::kCertFetchError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_CERT_FETCH_ERROR);
    case ErrorCode::kPolicyFetchError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_POLICY_FETCH_ERROR);
    case ErrorCode::kPolicyValidationError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_POLICY_VALIDATION_ERROR);
    case ErrorCode::kLockTimeout:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_LOCK_TIMEOUT_ERROR);
    case ErrorCode::kLockError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_LOCK_ERROR);
    case ErrorCode::kAlreadyLocked:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_ALREADY_LOCKED_ERROR);
    case ErrorCode::kOnlineStoreError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_ONLINE_STORE_ERROR);
    case ErrorCode::kMachineIdentificationError:
      return l10n_util::GetStringUTF16(
          IDS_DEMO_SETUP_NO_MACHINE_IDENTIFICATION_ERROR);
    case ErrorCode::kDMTokenStoreError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_DM_TOKEN_STORE_ERROR);
    case ErrorCode::kUnexpectedError:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_UNEXPECTED_ERROR);
  }
  NOTREACHED() << "No localized error message available for demo setup error.";
  return base::string16();
}

base::string16
DemoSetupController::DemoSetupError::GetLocalizedRecoveryMessage() const {
  switch (recovery_method_) {
    case RecoveryMethod::kRetry:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_RECOVERY_RETRY);
    case RecoveryMethod::kReboot:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_RECOVERY_REBOOT);
    case RecoveryMethod::kPowerwash:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_RECOVERY_POWERWASH);
    case RecoveryMethod::kCheckNetwork:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_RECOVERY_CHECK_NETWORK);
    case RecoveryMethod::kOnlineOnly:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_RECOVERY_OFFLINE_FATAL);
    case RecoveryMethod::kUnknown:
      return l10n_util::GetStringUTF16(IDS_DEMO_SETUP_RECOVERY_FATAL);
  }
  NOTREACHED()
      << "No localized error message available for demo setup recovery method.";
  return base::string16();
}

std::string DemoSetupController::DemoSetupError::GetDebugDescription() const {
  return base::StringPrintf("DemoSetupError (code: %d, recovery: %d) : %s",
                            error_code_, recovery_method_,
                            debug_message_.c_str());
}

void DemoSetupController::RegisterLocalStatePrefs(
    PrefRegistrySimple* registry) {
  registry->RegisterIntegerPref(
      prefs::kDemoModeConfig,
      static_cast<int>(DemoSession::DemoModeConfig::kNone));
}

// static
void DemoSetupController::ClearDemoRequisition(
    policy::DeviceCloudPolicyManagerChromeOS* policy_manager) {
  if (policy_manager->GetDeviceRequisition() == kDemoRequisition) {
    policy_manager->SetDeviceRequisition(std::string());
  }
}

// static
bool DemoSetupController::IsDemoModeAllowed() {
  // Demo mode is only allowed on devices that support ARC++.
  return arc::IsArcAvailable();
}

// static
bool DemoSetupController::IsOfflineDemoModeAllowed() {
  // Offline demo mode can be only enabled when demo mode feature is enabled.
  return IsDemoModeAllowed() &&
         base::CommandLine::ForCurrentProcess()->HasSwitch(
             switches::kEnableOfflineDemoMode);
}

// static
bool DemoSetupController::IsOobeDemoSetupFlowInProgress() {
  const WizardController* const wizard_controller =
      WizardController::default_controller();
  return wizard_controller &&
         wizard_controller->demo_setup_controller() != nullptr;
}

DemoSetupController::DemoSetupController() : weak_ptr_factory_(this) {}

DemoSetupController::~DemoSetupController() {
  if (device_local_account_policy_store_)
    device_local_account_policy_store_->RemoveObserver(this);
}

bool DemoSetupController::IsOfflineEnrollment() const {
  return demo_config_ == DemoSession::DemoModeConfig::kOffline;
}

void DemoSetupController::Enroll(OnSetupSuccess on_setup_success,
                                 OnSetupError on_setup_error) {
  DCHECK_NE(demo_config_, DemoSession::DemoModeConfig::kNone)
      << "Demo config needs to be explicitly set before calling Enroll()";
  DCHECK(!enrollment_helper_);

  on_setup_success_ = std::move(on_setup_success);
  on_setup_error_ = std::move(on_setup_error);

  VLOG(1) << "Starting demo setup "
          << DemoSession::DemoConfigToString(demo_config_);

  switch (demo_config_) {
    case DemoSession::DemoModeConfig::kOnline:
      LoadDemoResourcesCrOSComponent();
      return;
    case DemoSession::DemoModeConfig::kOffline: {
      const base::FilePath offline_data_dir =
          policy_dir_for_tests_.empty() ? base::FilePath(kOfflineDemoModeDir)
                                        : policy_dir_for_tests_;
      EnrollOffline(offline_data_dir);
      return;
    }
    case DemoSession::DemoModeConfig::kNone:
      NOTREACHED() << "No valid demo mode config specified";
  }
}

void DemoSetupController::LoadDemoResourcesCrOSComponent() {
  VLOG(1) << "Loading demo resources component";
  component_updater::CrOSComponentManager* cros_component_manager =
      g_browser_process->platform_part()->cros_component_manager();
  // In tests, use the desired error code.
  if (!cros_component_manager || DBusThreadManager::Get()->IsUsingFakes()) {
    base::SequencedTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&DemoSetupController::OnDemoResourcesCrOSComponentLoaded,
                       weak_ptr_factory_.GetWeakPtr(),
                       component_error_for_tests_, base::FilePath()));
    return;
  }

  cros_component_manager->Load(
      DemoResources::kDemoModeResourcesComponentName,
      component_updater::CrOSComponentManager::MountPolicy::kMount,
      component_updater::CrOSComponentManager::UpdatePolicy::kDontForce,
      base::BindOnce(&DemoSetupController::OnDemoResourcesCrOSComponentLoaded,
                     weak_ptr_factory_.GetWeakPtr()));
}

void DemoSetupController::OnDemoResourcesCrOSComponentLoaded(
    component_updater::CrOSComponentManager::Error error,
    const base::FilePath& path) {
  DCHECK_EQ(demo_config_, DemoSession::DemoModeConfig::kOnline);

  if (error != component_updater::CrOSComponentManager::Error::NONE) {
    SetupFailed(DemoSetupError::CreateFromComponentError(error));
    return;
  }

  VLOG(1) << "Starting online enrollment";
  policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
      g_browser_process->platform_part()
          ->browser_policy_connector_chromeos()
          ->GetDeviceCloudPolicyManager();
  DCHECK(policy_manager->GetDeviceRequisition().empty());
  policy_manager->SetDeviceRequisition(kDemoRequisition);
  policy::EnrollmentConfig config;
  config.mode = policy::EnrollmentConfig::MODE_ATTESTATION;
  config.management_domain = DemoSetupController::kDemoModeDomain;

  enrollment_helper_ = EnterpriseEnrollmentHelper::Create(
      this, nullptr, config, DemoSetupController::kDemoModeDomain);
  enrollment_helper_->EnrollUsingAttestation();
}

void DemoSetupController::EnrollOffline(const base::FilePath& policy_dir) {
  DCHECK_EQ(demo_config_, DemoSession::DemoModeConfig::kOffline);
  DCHECK(policy_dir_.empty());
  policy_dir_ = policy_dir;

  if (IsOnlineFreCheckRequired()) {
    SetupFailed(
        DemoSetupError(DemoSetupError::ErrorCode::kOnlineFRECheckRequired,
                       DemoSetupError::RecoveryMethod::kOnlineOnly,
                       "Cannot do offline demo mode setup, because online "
                       "FRE check is required."));
    return;
  }

  VLOG(1) << "Checking if offline policy exists";
  std::string* message = new std::string();
  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE,
      {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
      base::BindOnce(&CheckOfflinePolicyFilesExist, policy_dir_, message),
      base::BindOnce(&DemoSetupController::OnOfflinePolicyFilesExisted,
                     weak_ptr_factory_.GetWeakPtr(), base::Owned(message)));
}

void DemoSetupController::OnOfflinePolicyFilesExisted(std::string* message,
                                                      bool ok) {
  DCHECK_EQ(demo_config_, DemoSession::DemoModeConfig::kOffline);
  DCHECK(!policy_dir_.empty());

  if (!ok) {
    SetupFailed(DemoSetupError(DemoSetupError::ErrorCode::kNoOfflineResources,
                               DemoSetupError::RecoveryMethod::kOnlineOnly,
                               *message));
    return;
  }

  VLOG(1) << "Starting offline enrollment";
  policy::EnrollmentConfig config;
  config.mode = policy::EnrollmentConfig::MODE_OFFLINE_DEMO;
  config.management_domain = DemoSetupController::kDemoModeDomain;
  config.offline_policy_path =
      policy_dir_.AppendASCII(kOfflineDevicePolicyFileName);
  enrollment_helper_ = EnterpriseEnrollmentHelper::Create(
      this, nullptr /* ad_join_delegate */, config,
      DemoSetupController::kDemoModeDomain);
  enrollment_helper_->EnrollForOfflineDemo();
}

void DemoSetupController::OnAuthError(const GoogleServiceAuthError& error) {
  NOTREACHED();
}

void DemoSetupController::OnEnrollmentError(policy::EnrollmentStatus status) {
  SetupFailed(DemoSetupError::CreateFromEnrollmentStatus(status));
}

void DemoSetupController::OnOtherError(
    EnterpriseEnrollmentHelper::OtherError error) {
  SetupFailed(DemoSetupError::CreateFromOtherEnrollmentError(error));
}

void DemoSetupController::OnDeviceEnrolled() {
  DCHECK_NE(demo_config_, DemoSession::DemoModeConfig::kNone);

  // Try to load the policy for the device local account.
  if (demo_config_ == DemoSession::DemoModeConfig::kOffline) {
    VLOG(1) << "Loading offline policy";
    DCHECK(!policy_dir_.empty());
    const base::FilePath file_path =
        policy_dir_.AppendASCII(kOfflineDeviceLocalAccountPolicyFileName);
    base::PostTaskWithTraitsAndReplyWithResult(
        FROM_HERE,
        {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
        base::BindOnce(&ReadFileToOptionalString, file_path),
        base::BindOnce(&DemoSetupController::OnDeviceLocalAccountPolicyLoaded,
                       weak_ptr_factory_.GetWeakPtr()));
    return;
  }
  VLOG(1) << "Marking device registered";
  StartupUtils::MarkDeviceRegistered(
      base::BindOnce(&DemoSetupController::OnDeviceRegistered,
                     weak_ptr_factory_.GetWeakPtr()));
}

void DemoSetupController::OnMultipleLicensesAvailable(
    const EnrollmentLicenseMap& licenses) {
  NOTREACHED();
}

void DemoSetupController::OnDeviceAttributeUploadCompleted(bool success) {
  NOTREACHED();
}

void DemoSetupController::OnDeviceAttributeUpdatePermission(bool granted) {
  NOTREACHED();
}

void DemoSetupController::OnRestoreAfterRollbackCompleted() {
  NOTREACHED();
}

void DemoSetupController::SetCrOSComponentLoadErrorForTest(
    component_updater::CrOSComponentManager::Error error) {
  component_error_for_tests_ = error;
}

void DemoSetupController::SetDeviceLocalAccountPolicyStoreForTest(
    policy::CloudPolicyStore* store) {
  device_local_account_policy_store_ = store;
}

void DemoSetupController::SetOfflineDataDirForTest(
    const base::FilePath& offline_dir) {
  policy_dir_for_tests_ = offline_dir;
}

void DemoSetupController::OnDeviceLocalAccountPolicyLoaded(
    base::Optional<std::string> blob) {
  if (!blob.has_value()) {
    // This is very unlikely to happen since the file existence is already
    // checked as CheckOfflinePolicyFilesExist.
    SetupFailed(
        DemoSetupError(DemoSetupError::ErrorCode::kOfflinePolicyError,
                       DemoSetupError::RecoveryMethod::kPowerwash,
                       "Policy file for the device local account not found"));
    return;
  }

  enterprise_management::PolicyFetchResponse policy;
  if (!policy.ParseFromString(blob.value())) {
    SetupFailed(DemoSetupError(DemoSetupError::ErrorCode::kOfflinePolicyError,
                               DemoSetupError::RecoveryMethod::kPowerwash,
                               "Error parsing local account policy blob."));
    return;
  }

  // Extract the account_id from the policy data.
  enterprise_management::PolicyData policy_data;
  if (policy.policy_data().empty() ||
      !policy_data.ParseFromString(policy.policy_data())) {
    SetupFailed(DemoSetupError(DemoSetupError::ErrorCode::kOfflinePolicyError,
                               DemoSetupError::RecoveryMethod::kPowerwash,
                               "Error parsing local account policy data."));
    return;
  }

  VLOG(1) << "Storing offline policy";
  // On the unittest, the device_local_account_policy_store_ is already
  // initialized. Otherwise attempts to get the store.
  if (!device_local_account_policy_store_) {
    device_local_account_policy_store_ =
        GetDeviceLocalAccountPolicyStore(policy_data.username());
  }

  if (!device_local_account_policy_store_) {
    SetupFailed(
        DemoSetupError(DemoSetupError::ErrorCode::kOfflinePolicyStoreError,
                       DemoSetupError::RecoveryMethod::kPowerwash,
                       "Can't find the store for the local account policy."));
    return;
  }
  device_local_account_policy_store_->AddObserver(this);
  device_local_account_policy_store_->Store(policy);
}

void DemoSetupController::OnDeviceRegistered() {
  VLOG(1) << "Demo mode setup finished successfully.";
  PrefService* prefs = g_browser_process->local_state();
  prefs->SetInteger(prefs::kDemoModeConfig, static_cast<int>(demo_config_));
  prefs->CommitPendingWrite();
  Reset();
  if (!on_setup_success_.is_null())
    std::move(on_setup_success_).Run();
}

void DemoSetupController::SetupFailed(const DemoSetupError& error) {
  Reset();
  LOG(ERROR) << error.GetDebugDescription();
  if (!on_setup_error_.is_null())
    std::move(on_setup_error_).Run(error);
}

void DemoSetupController::Reset() {
  DCHECK_NE(demo_config_, DemoSession::DemoModeConfig::kNone);
  DCHECK_NE(demo_config_ == DemoSession::DemoModeConfig::kOffline,
            policy_dir_.empty());

  // |demo_config_| is not reset here, because it is needed for retrying setup.
  enrollment_helper_.reset();
  policy_dir_.clear();
  if (device_local_account_policy_store_) {
    device_local_account_policy_store_->RemoveObserver(this);
    device_local_account_policy_store_ = nullptr;
  }
  policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
      g_browser_process->platform_part()
          ->browser_policy_connector_chromeos()
          ->GetDeviceCloudPolicyManager();
  ClearDemoRequisition(policy_manager);
}

void DemoSetupController::OnStoreLoaded(policy::CloudPolicyStore* store) {
  DCHECK_EQ(store, device_local_account_policy_store_);
  VLOG(1) << "Marking device registered";
  StartupUtils::MarkDeviceRegistered(
      base::BindOnce(&DemoSetupController::OnDeviceRegistered,
                     weak_ptr_factory_.GetWeakPtr()));
}

void DemoSetupController::OnStoreError(policy::CloudPolicyStore* store) {
  DCHECK_EQ(store, device_local_account_policy_store_);
  SetupFailed(
      DemoSetupError(DemoSetupError::ErrorCode::kOfflinePolicyStoreError,
                     DemoSetupError::RecoveryMethod::kPowerwash,
                     "Failed to store the local account policy"));
}

}  //  namespace chromeos
