// Copyright 2018 The Chromium OS 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 "cryptohome/bootlockbox/boot_lockbox_client.h"

#include <utility>
#include <vector>

#include <base/timer/elapsed_timer.h>
#include <brillo/glib/object.h>
#include <dbus/cryptohome/dbus-constants.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus.h>

// Note that boot_lockbox_rpc.pb.h have to be included before
// dbus_adaptors/org.chromium.BootLockboxInterface.h because it is used in
// there.
#include "boot_lockbox_rpc.pb.h"  // NOLINT(build/include)

#include "bootlockbox/dbus-proxies.h"

namespace cryptohome {

std::unique_ptr<BootLockboxClient>
BootLockboxClient::CreateBootLockboxClient() {
  dbus::Bus::Options options;
  options.bus_type = dbus::Bus::SYSTEM;
  scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
  if (!bus->Connect()) {
    LOG(ERROR) << "D-Bus system bus is not ready";
    return nullptr;
  }

  auto bootlockbox_proxy =
      std::make_unique<org::chromium::BootLockboxInterfaceProxy>(bus);

  return std::unique_ptr<BootLockboxClient>(
      new BootLockboxClient(std::move(bootlockbox_proxy), bus));
}

BootLockboxClient::BootLockboxClient(
    std::unique_ptr<org::chromium::BootLockboxInterfaceProxy> bootlockbox,
    scoped_refptr<dbus::Bus> bus)
    : bootlockbox_(std::move(bootlockbox)), bus_(bus) {}

BootLockboxClient::~BootLockboxClient() {
  bus_->ShutdownAndBlock();
}

bool BootLockboxClient::Store(const std::string& key,
                              const std::string& digest) {
  base::ElapsedTimer timer;
  cryptohome::StoreBootLockboxRequest request;
  request.set_key(key);
  request.set_data(digest);

  cryptohome::StoreBootLockboxReply reply;
  brillo::ErrorPtr error;
  if (!bootlockbox_->StoreBootLockbox(request, &reply, &error)) {
    LOG(ERROR) << "Failed to call StoreBootLockbox, error: "
               << error->GetMessage();
    return false;
  }

  if (reply.has_error()) {
    LOG(ERROR) << "Failed to call Store, error code: " << reply.error();
    return false;
  }

  VLOG(1) << "BootLockboxClient::Store took "
          << timer.Elapsed().InMillisecondsRoundedUp() << "ms";
  return true;
}

bool BootLockboxClient::Read(const std::string& key,
                             std::string* digest) {
  base::ElapsedTimer timer;
  cryptohome::ReadBootLockboxRequest request;
  request.set_key(key);

  cryptohome::ReadBootLockboxReply reply;
  brillo::ErrorPtr error;
  if (!bootlockbox_->ReadBootLockbox(request, &reply, &error)) {
    LOG(ERROR) << "Failed to call ReadBootLockbox, error: "
               << error->GetMessage();
    return false;
  }

  if (reply.has_error()) {
    LOG(ERROR) << "Failed to call ReadBootLockbox, error code: "
               << reply.error();
    return false;
  }
  if (!reply.has_data()) {
    LOG(ERROR) << "Missing data field in ReadBootLockboxReply";
    return false;
  }
  *digest = reply.data();
  return true;
}

bool BootLockboxClient::Finalize() {
  base::ElapsedTimer timer;
  cryptohome::FinalizeNVRamBootLockboxRequest request;

  cryptohome::FinalizeBootLockboxReply reply;
  brillo::ErrorPtr error;
  if (!bootlockbox_->FinalizeBootLockbox(request, &reply, &error)) {
    LOG(ERROR) << "Failed to call FinalizeBootLockbox";
    return false;
  }

  if (reply.has_error()) {
    LOG(ERROR) << "Error calling FinalizeBootLockbox, error code: "
               << reply.error();
    return false;
  }
  VLOG(1) << "BootLockboxClient::Finalize took "
          << timer.Elapsed().InMillisecondsRoundedUp() << "ms";
  return true;
}

}  // namespace cryptohome
