// Copyright 2016 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/policy/dm_token_storage.h"

#include "base/bind.h"
#include "base/task_scheduler/post_task.h"
#include "chrome/browser/chromeos/settings/token_encryptor.h"
#include "chrome/common/pref_names.h"
#include "chromeos/cryptohome/system_salt_getter.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"

namespace {

std::string EncryptToken(const std::string& system_salt,
                         const std::string& dm_token) {
  chromeos::CryptohomeTokenEncryptor encryptor(system_salt);
  return encryptor.EncryptWithSystemSalt(dm_token);
}

std::string DecryptToken(const std::string& system_salt,
                         const std::string encrypted_dm_token) {
  chromeos::CryptohomeTokenEncryptor encryptor(system_salt);
  return encryptor.DecryptWithSystemSalt(encrypted_dm_token);
}

}  // namespace

namespace policy {

DMTokenStorage::DMTokenStorage(PrefService* local_state)
    : local_state_(local_state), weak_ptr_factory_(this) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  chromeos::SystemSaltGetter::Get()->GetSystemSalt(base::Bind(
      &DMTokenStorage::OnSystemSaltRecevied, weak_ptr_factory_.GetWeakPtr()));
}

DMTokenStorage::~DMTokenStorage() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  FlushStoreTokenCallback(false);
  FlushRetrieveTokenCallback(std::string());
}

// static
void DMTokenStorage::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterStringPref(prefs::kDeviceDMToken, std::string());
}

void DMTokenStorage::StoreDMToken(const std::string& dm_token,
                                  StoreCallback callback) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (!store_callback_.is_null()) {
    DLOG(ERROR)
        << "Failed to store DM token: Previous store operation is not finished";
    std::move(callback).Run(false);
    return;
  }
  if (!retrieve_callbacks_.empty()) {
    DLOG(ERROR)
        << "Failed to store DM token: Retrieve operation is not finished";
    std::move(callback).Run(false);
    return;
  }
  store_callback_ = std::move(callback);
  dm_token_ = dm_token;
  switch (state_) {
    case SaltState::LOADING:
      // Do nothing. Waiting for system salt.
      break;
    case SaltState::LOADED:
      EncryptAndStoreToken();
      break;
    case SaltState::ERROR:
      FlushStoreTokenCallback(false);
      break;
  }
}

void DMTokenStorage::RetrieveDMToken(RetrieveCallback callback) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (!store_callback_.is_null()) {
    DCHECK(retrieve_callbacks_.empty());
    DLOG(ERROR)
        << "Failed to retrieve DM token: Store operation is not finished";
    std::move(callback).Run(std::string());
    return;
  }
  retrieve_callbacks_.push_back(std::move(callback));
  switch (state_) {
    case SaltState::LOADING:
      // Do nothing. Waiting for system salt.
      break;
    case SaltState::LOADED:
      if (retrieve_callbacks_.size() == 1) {  // First consumer.
        LoadAndDecryptToken();
      }
      break;
    case SaltState::ERROR:
      FlushRetrieveTokenCallback(std::string());
      break;
  }
}

void DMTokenStorage::OnSystemSaltRecevied(const std::string& system_salt) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  system_salt_ = system_salt;
  if (system_salt_.empty()) {
    state_ = SaltState::ERROR;
    DLOG(ERROR) << "Failed to get system salt.";
    FlushStoreTokenCallback(false);
    FlushRetrieveTokenCallback(std::string());
    return;
  }
  // Should not be concurrent store and get operations.
  DCHECK(store_callback_.is_null() || retrieve_callbacks_.empty());
  state_ = SaltState::LOADED;
  if (!store_callback_.is_null())
    EncryptAndStoreToken();
  else if (!retrieve_callbacks_.empty())
    LoadAndDecryptToken();
}

void DMTokenStorage::EncryptAndStoreToken() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(!system_salt_.empty());
  DCHECK(!dm_token_.empty());
  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
      base::Bind(&EncryptToken, system_salt_, dm_token_),
      base::Bind(&DMTokenStorage::OnTokenEncrypted,
                 weak_ptr_factory_.GetWeakPtr()));
}

void DMTokenStorage::OnTokenEncrypted(const std::string& encrypted_dm_token) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (encrypted_dm_token.empty()) {
    DLOG(ERROR) << "Failed to encrypt DM token.";
  } else {
    local_state_->SetString(prefs::kDeviceDMToken, encrypted_dm_token);
  }
  FlushStoreTokenCallback(!encrypted_dm_token.empty());
}

void DMTokenStorage::LoadAndDecryptToken() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK_EQ(SaltState::LOADED, state_);
  std::string encrypted_dm_token =
      local_state_->GetString(prefs::kDeviceDMToken);
  if (!encrypted_dm_token.empty()) {
    base::PostTaskWithTraitsAndReplyWithResult(
        FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
        base::Bind(&DecryptToken, system_salt_, encrypted_dm_token),
        base::Bind(&DMTokenStorage::FlushRetrieveTokenCallback,
                   weak_ptr_factory_.GetWeakPtr()));
  } else {
    DLOG(ERROR) << "No DM token in the local state.";
    FlushRetrieveTokenCallback(std::string());
  }
}

void DMTokenStorage::FlushStoreTokenCallback(bool status) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (!store_callback_.is_null()) {
    std::move(store_callback_).Run(status);
  }
}

void DMTokenStorage::FlushRetrieveTokenCallback(const std::string& dm_token) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (retrieve_callbacks_.empty())
    return;
  if (dm_token.empty())
    DLOG(ERROR) << "Failed to retrieve DM token.";
  std::vector<RetrieveCallback> callbacks;
  callbacks.swap(retrieve_callbacks_);
  for (RetrieveCallback& callback : callbacks)
    std::move(callback).Run(dm_token);
}

}  // namespace policy
