// Copyright 2013 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/managed_mode/managed_user_registration_utility.h"

#include "base/base64.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/prefs/pref_service.h"
#include "base/rand_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/managed_mode/managed_user_refresh_token_fetcher.h"
#include "chrome/browser/managed_mode/managed_user_service.h"
#include "chrome/browser/managed_mode/managed_user_service_factory.h"
#include "chrome/browser/managed_mode/managed_user_sync_service.h"
#include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/browser/signin/profile_oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/sync/glue/device_info.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"

using base::DictionaryValue;

namespace {

const char kAcknowledged[] = "acknowledged";
const char kName[] = "name";
const char kMasterKey[] = "masterKey";

ManagedUserRegistrationUtility* g_instance_for_tests = NULL;

// Actual implementation of ManagedUserRegistrationUtility.
class ManagedUserRegistrationUtilityImpl
    : public ManagedUserRegistrationUtility,
      public ManagedUserSyncServiceObserver {
 public:
  ManagedUserRegistrationUtilityImpl(
      PrefService* prefs,
      scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
      ManagedUserSyncService* service);

  virtual ~ManagedUserRegistrationUtilityImpl();

  // Registers a new managed user with the server. |managed_user_id| is a new
  // unique ID for the new managed user. If its value is the same as that of
  // of one of the existing managed users, then the same user will be created
  // on this machine. |info| contains necessary information like the display
  // name of the  the user. |callback| is called with the result of the
  // registration. We use the info here and not the profile, because on
  // Chrome OS the profile of the managed user does not yet exist.
  virtual void Register(const std::string& managed_user_id,
                        const ManagedUserRegistrationInfo& info,
                        const RegistrationCallback& callback) OVERRIDE;

  // ManagedUserSyncServiceObserver:
  virtual void OnManagedUserAcknowledged(const std::string& managed_user_id)
      OVERRIDE;
  virtual void OnManagedUsersSyncingStopped() OVERRIDE;

 private:
  // Fetches the managed user token when we have the device name.
  void FetchToken(const std::string& client_name);

  // Called when we have received a token for the managed user.
  void OnReceivedToken(const GoogleServiceAuthError& error,
                       const std::string& token);

  // Dispatches the callback and cleans up if all the conditions have been met.
  void CompleteRegistrationIfReady();

  // Aborts any registration currently in progress. If |run_callback| is true,
  // calls the callback specified in Register() with the given |error|.
  void AbortPendingRegistration(bool run_callback,
                                const GoogleServiceAuthError& error);

  // If |run_callback| is true, dispatches the callback with the saved token
  // (which may be empty) and the given |error|. In any case, resets internal
  // variables to be ready for the next registration.
  void CompleteRegistration(bool run_callback,
                            const GoogleServiceAuthError& error);

  // Cancels any registration currently in progress, without calling the
  // callback or reporting an error.
  void CancelPendingRegistration();

  base::WeakPtrFactory<ManagedUserRegistrationUtilityImpl> weak_ptr_factory_;
  PrefService* prefs_;
  scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher_;

  // A |BrowserContextKeyedService| owned by the custodian profile.
  ManagedUserSyncService* managed_user_sync_service_;

  std::string pending_managed_user_id_;
  std::string pending_managed_user_token_;
  bool pending_managed_user_acknowledged_;
  bool is_existing_managed_user_;
  RegistrationCallback callback_;

  DISALLOW_COPY_AND_ASSIGN(ManagedUserRegistrationUtilityImpl);
};

} // namespace

ManagedUserRegistrationInfo::ManagedUserRegistrationInfo(const string16& name,
                                                         int avatar_index)
    : avatar_index(avatar_index),
      name(name) {
}

ScopedTestingManagedUserRegistrationUtility::
    ScopedTestingManagedUserRegistrationUtility(
        ManagedUserRegistrationUtility* instance) {
  ManagedUserRegistrationUtility::SetUtilityForTests(instance);
}

ScopedTestingManagedUserRegistrationUtility::
    ~ScopedTestingManagedUserRegistrationUtility() {
  ManagedUserRegistrationUtility::SetUtilityForTests(NULL);
}

// static
scoped_ptr<ManagedUserRegistrationUtility>
ManagedUserRegistrationUtility::Create(Profile* profile) {
  if (g_instance_for_tests) {
    ManagedUserRegistrationUtility* result = g_instance_for_tests;
    g_instance_for_tests = NULL;
    return make_scoped_ptr(result);
  }
  scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher =
      ManagedUserRefreshTokenFetcher::Create(
          ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
          profile->GetRequestContext());
  ManagedUserSyncService* managed_user_sync_service =
      ManagedUserSyncServiceFactory::GetForProfile(profile);
  return make_scoped_ptr(ManagedUserRegistrationUtility::CreateImpl(
      profile->GetPrefs(),
      token_fetcher.Pass(),
      managed_user_sync_service));
}

// static
std::string ManagedUserRegistrationUtility::GenerateNewManagedUserId() {
  std::string new_managed_user_id;
  bool success = base::Base64Encode(base::RandBytesAsString(8),
                                    &new_managed_user_id);
  DCHECK(success);
  return new_managed_user_id;
}

// static
void ManagedUserRegistrationUtility::SetUtilityForTests(
    ManagedUserRegistrationUtility* utility) {
  if (g_instance_for_tests)
    delete g_instance_for_tests;
  g_instance_for_tests = utility;
}

// static
ManagedUserRegistrationUtility* ManagedUserRegistrationUtility::CreateImpl(
      PrefService* prefs,
      scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
      ManagedUserSyncService* service) {
  return new ManagedUserRegistrationUtilityImpl(prefs,
                                                token_fetcher.Pass(),
                                                service);
}

namespace {

ManagedUserRegistrationUtilityImpl::ManagedUserRegistrationUtilityImpl(
    PrefService* prefs,
    scoped_ptr<ManagedUserRefreshTokenFetcher> token_fetcher,
    ManagedUserSyncService* service)
    : weak_ptr_factory_(this),
      prefs_(prefs),
      token_fetcher_(token_fetcher.Pass()),
      managed_user_sync_service_(service),
      pending_managed_user_acknowledged_(false),
      is_existing_managed_user_(false) {
  managed_user_sync_service_->AddObserver(this);
}

ManagedUserRegistrationUtilityImpl::~ManagedUserRegistrationUtilityImpl() {
  managed_user_sync_service_->RemoveObserver(this);
  CancelPendingRegistration();
}

void ManagedUserRegistrationUtilityImpl::Register(
    const std::string& managed_user_id,
    const ManagedUserRegistrationInfo& info,
    const RegistrationCallback& callback) {
  DCHECK(pending_managed_user_id_.empty());
  callback_ = callback;
  pending_managed_user_id_ = managed_user_id;

  const DictionaryValue* dict = prefs_->GetDictionary(prefs::kManagedUsers);
  is_existing_managed_user_ = dict->HasKey(managed_user_id);
  if (!is_existing_managed_user_) {
    managed_user_sync_service_->AddManagedUser(pending_managed_user_id_,
                                               base::UTF16ToUTF8(info.name),
                                               info.master_key,
                                               info.avatar_index);
  } else {
    // User already exists, don't wait for acknowledgment.
    OnManagedUserAcknowledged(managed_user_id);
  }

  browser_sync::DeviceInfo::GetClientName(
      base::Bind(&ManagedUserRegistrationUtilityImpl::FetchToken,
                 weak_ptr_factory_.GetWeakPtr()));
}

void ManagedUserRegistrationUtilityImpl::CancelPendingRegistration() {
  AbortPendingRegistration(
      false,  // Don't run the callback. The error will be ignored.
      GoogleServiceAuthError(GoogleServiceAuthError::NONE));
}

void ManagedUserRegistrationUtilityImpl::OnManagedUserAcknowledged(
    const std::string& managed_user_id) {
  DCHECK_EQ(pending_managed_user_id_, managed_user_id);
  DCHECK(!pending_managed_user_acknowledged_);
  pending_managed_user_acknowledged_ = true;
  CompleteRegistrationIfReady();
}

void ManagedUserRegistrationUtilityImpl::OnManagedUsersSyncingStopped() {
  AbortPendingRegistration(
      true,  // Run the callback.
      GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
}

void ManagedUserRegistrationUtilityImpl::FetchToken(
    const std::string& client_name) {
  token_fetcher_->Start(
      pending_managed_user_id_, client_name,
      base::Bind(&ManagedUserRegistrationUtilityImpl::OnReceivedToken,
                 weak_ptr_factory_.GetWeakPtr()));
}

void ManagedUserRegistrationUtilityImpl::OnReceivedToken(
    const GoogleServiceAuthError& error,
    const std::string& token) {
  if (error.state() != GoogleServiceAuthError::NONE) {
    CompleteRegistration(true, error);
    return;
  }

  DCHECK(!token.empty());
  pending_managed_user_token_ = token;
  CompleteRegistrationIfReady();
}

void ManagedUserRegistrationUtilityImpl::CompleteRegistrationIfReady() {
  bool require_acknowledgment =
      !pending_managed_user_acknowledged_ &&
      !CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kNoManagedUserAcknowledgmentCheck);
  if (require_acknowledgment || pending_managed_user_token_.empty())
    return;

  GoogleServiceAuthError error(GoogleServiceAuthError::NONE);
  CompleteRegistration(true, error);
}

void ManagedUserRegistrationUtilityImpl::AbortPendingRegistration(
    bool run_callback,
    const GoogleServiceAuthError& error) {
  pending_managed_user_token_.clear();
  CompleteRegistration(run_callback, error);
}

void ManagedUserRegistrationUtilityImpl::CompleteRegistration(
    bool run_callback,
    const GoogleServiceAuthError& error) {
  if (callback_.is_null())
    return;

  // We check that the user being registered is not an existing managed
  // user before deleting it from sync to avoid accidental deletion of
  // existing managed users by just canceling the registration for example.
  if (pending_managed_user_token_.empty() && !is_existing_managed_user_) {
    DCHECK(!pending_managed_user_id_.empty());
    // Remove the pending managed user if we weren't successful.
    DictionaryPrefUpdate update(prefs_, prefs::kManagedUsers);
    bool success =
        update->RemoveWithoutPathExpansion(pending_managed_user_id_, NULL);
    DCHECK(success);
    managed_user_sync_service_->DeleteManagedUser(pending_managed_user_id_);
  }

  if (run_callback)
    callback_.Run(error, pending_managed_user_token_);
  callback_.Reset();
}

} // namespace
