// Copyright 2019 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 "components/sync/driver/file_based_trusted_vault_client.h"

#include <utility>

#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/files/important_file_writer.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/task_runner_util.h"
#include "components/os_crypt/os_crypt.h"
#include "components/sync/protocol/local_trusted_vault.pb.h"

namespace syncer {

namespace {

constexpr base::TaskTraits kTaskTraits = {
    base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE,
    base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN};

sync_pb::LocalTrustedVault ReadEncryptedFile(const base::FilePath& file_path) {
  sync_pb::LocalTrustedVault proto;
  std::string ciphertext;
  std::string decrypted_content;
  if (base::ReadFileToString(file_path, &ciphertext) &&
      OSCrypt::DecryptString(ciphertext, &decrypted_content)) {
    proto.ParseFromString(decrypted_content);
  }

  return proto;
}

void WriteToDisk(const sync_pb::LocalTrustedVault& data,
                 const base::FilePath& file_path) {
  std::string encrypted_data;
  if (!OSCrypt::EncryptString(data.SerializeAsString(), &encrypted_data)) {
    DLOG(ERROR) << "Failed to encrypt trusted vault file.";
    return;
  }

  if (!base::ImportantFileWriter::WriteFileAtomically(file_path,
                                                      encrypted_data)) {
    DLOG(ERROR) << "Failed to write trusted vault file.";
  }
}

}  // namespace

//
class FileBasedTrustedVaultClient::Backend
    : public base::RefCountedThreadSafe<Backend> {
 public:
  explicit Backend(const base::FilePath& file_path) : file_path_(file_path) {}

  void ReadDataFromDisk() { data_ = ReadEncryptedFile(file_path_); }

  std::vector<std::vector<uint8_t>> FetchKeys(const std::string& gaia_id) {
    const sync_pb::LocalTrustedVaultPerUser* per_user_vault =
        FindUserVault(gaia_id);

    std::vector<std::vector<uint8_t>> keys;
    if (per_user_vault) {
      for (const sync_pb::LocalTrustedVaultKey& key : per_user_vault->key()) {
        const std::string& key_material = key.key_material();
        keys.emplace_back(key_material.begin(), key_material.end());
      }
    }

    return keys;
  }

  void StoreKeys(const std::string& gaia_id,
                 const std::vector<std::vector<uint8_t>>& keys) {
    // Find or create user for |gaid_id|.
    sync_pb::LocalTrustedVaultPerUser* per_user_vault = FindUserVault(gaia_id);
    if (!per_user_vault) {
      per_user_vault = data_.add_user();
      per_user_vault->set_gaia_id(gaia_id);
    }

    // Replace all keys.
    per_user_vault->clear_key();
    for (const std::vector<uint8_t>& key : keys) {
      per_user_vault->add_key()->set_key_material(key.data(), key.size());
    }

    WriteToDisk(data_, file_path_);
  }

 private:
  friend class base::RefCountedThreadSafe<Backend>;

  ~Backend() = default;

  // Finds the per-user vault in |data_| for |gaia_id|. Returns null if not
  // found.
  sync_pb::LocalTrustedVaultPerUser* FindUserVault(const std::string& gaia_id) {
    for (int i = 0; i < data_.user_size(); ++i) {
      if (data_.user(i).gaia_id() == gaia_id) {
        return data_.mutable_user(i);
      }
    }
    return nullptr;
  }

  const base::FilePath file_path_;

  sync_pb::LocalTrustedVault data_;

  DISALLOW_COPY_AND_ASSIGN(Backend);
};

FileBasedTrustedVaultClient::FileBasedTrustedVaultClient(
    const base::FilePath& file_path)
    : file_path_(file_path),
      backend_task_runner_(base::CreateSequencedTaskRunner(kTaskTraits)) {}

FileBasedTrustedVaultClient::~FileBasedTrustedVaultClient() = default;

std::unique_ptr<FileBasedTrustedVaultClient::Subscription>
FileBasedTrustedVaultClient::AddKeysChangedObserver(
    const base::RepeatingClosure& cb) {
  return observer_list_.Add(cb);
}

void FileBasedTrustedVaultClient::FetchKeys(
    const std::string& gaia_id,
    base::OnceCallback<void(const std::vector<std::vector<uint8_t>>&)> cb) {
  TriggerLazyInitializationIfNeeded();
  base::PostTaskAndReplyWithResult(
      backend_task_runner_.get(), FROM_HERE,
      base::BindOnce(&Backend::FetchKeys, backend_, gaia_id), std::move(cb));
}

void FileBasedTrustedVaultClient::StoreKeys(
    const std::string& gaia_id,
    const std::vector<std::vector<uint8_t>>& keys) {
  TriggerLazyInitializationIfNeeded();
  backend_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&Backend::StoreKeys, backend_, gaia_id, keys));
  observer_list_.Notify();
}

void FileBasedTrustedVaultClient::WaitForFlushForTesting(
    base::OnceClosure cb) const {
  backend_task_runner_->PostTaskAndReply(FROM_HERE, base::DoNothing(),
                                         std::move(cb));
}

void FileBasedTrustedVaultClient::TriggerLazyInitializationIfNeeded() {
  if (backend_) {
    return;
  }

  backend_ = base::MakeRefCounted<Backend>(file_path_);
  backend_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&Backend::ReadDataFromDisk, backend_));
}

bool FileBasedTrustedVaultClient::IsInitializationTriggeredForTesting() const {
  return backend_ != nullptr;
}

}  // namespace syncer
