// Copyright 2016 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 <stdio.h>
#include <string>

#include <base/logging.h>
#include <base/macros.h>
#include <base/message_loop/message_loop.h>
#include <base/run_loop.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/bind_lambda.h>
#include <brillo/secure_blob.h>

#include "attestation/client/dbus_proxy.h"
#include "attestation/common/print_interface_proto.h"
#include "cryptohome/tpm.h"
#include "tpm_manager/client/tpm_ownership_dbus_proxy.h"
#include "tpm_manager/common/print_tpm_manager_proto.h"

namespace cryptohome {

namespace tpm_manager {

using attestation::AttestationStatus;

template <typename MethodType, typename ReplyProtoType>
void SendAndWait(const MethodType& method,
                 ReplyProtoType* reply_proto) {
  base::RunLoop loop;
  auto callback = base::Bind(
      [](ReplyProtoType* reply_proto, base::RunLoop* loop,
         const ReplyProtoType& reply) {
        *reply_proto = reply;
        loop->Quit();
      },
      reply_proto, &loop);
  method.Run(callback);
  loop.Run();
}

int TakeOwnership(bool finalize) {
  base::MessageLoop loop(base::MessageLoop::TYPE_IO);
  base::Time start_time = base::Time::Now();
  ::tpm_manager::TpmOwnershipDBusProxy proxy;
  if (!proxy.Initialize()) {
    LOG(ERROR) << "Failed to start tpm ownership proxy";
    return -1;
  }
  LOG(INFO) << "Initializing TPM.";
  ::tpm_manager::TakeOwnershipRequest request;
  auto method = base::Bind(&::tpm_manager::TpmOwnershipDBusProxy::TakeOwnership,
                           base::Unretained(&proxy), request);
  ::tpm_manager::TakeOwnershipReply reply;
  SendAndWait(method, &reply);
  if (reply.status() != ::tpm_manager::STATUS_SUCCESS) {
    LOG(ERROR) << "Failed to take ownership.";
    puts(GetProtoDebugString(reply).c_str());
    return -1;
  }
  if (finalize) {
    LOG(WARNING) << "Finalization is ignored for TPM2.0";
  }
  base::TimeDelta duration = base::Time::Now() - start_time;
  LOG(INFO) << "TPM initialization successful ("
            << duration.InMilliseconds() << " ms).";
  return 0;
}

int VerifyEK(bool is_cros_core) {
  base::MessageLoop loop(base::MessageLoop::TYPE_IO);
  attestation::DBusProxy proxy;
  if (!proxy.Initialize()) {
    LOG(ERROR) << "Failed to start attestation proxy";
    return -1;
  }
  attestation::VerifyRequest request;
  request.set_cros_core(is_cros_core);
  request.set_ek_only(true);
  auto method = base::Bind(&attestation::DBusProxy::Verify,
                           base::Unretained(&proxy), request);
  attestation::VerifyReply reply;
  SendAndWait(method, &reply);
  if (reply.status() != AttestationStatus::STATUS_SUCCESS) {
    LOG(ERROR) << "Failed to verify TPM endorsement.";
    puts(GetProtoDebugString(reply).c_str());
    return -1;
  }
  if (!reply.verified()) {
    LOG(ERROR) << "TPM endorsement verification failed.";
    return -1;
  }
  LOG(INFO) << "TPM endorsement verified successfully.";
  return 0;
}

int DumpStatus() {
  LOG(ERROR) << "Not implemented";
  return -1;
}

int GetRandom(unsigned int random_bytes_count) {
  cryptohome::Tpm* tpm = cryptohome::Tpm::GetSingleton();
  brillo::SecureBlob random_bytes;
  tpm->GetRandomData(random_bytes_count, &random_bytes);
  if (random_bytes_count != random_bytes.size())
    return -1;

  std::string hex_bytes =
      base::HexEncode(random_bytes.data(), random_bytes.size());
  puts(hex_bytes.c_str());
  return 0;
}

bool GetVersionInfo(cryptohome::Tpm::TpmVersionInfo* version_info) {
  base::MessageLoop loop(base::MessageLoop::TYPE_IO);
  ::tpm_manager::TpmOwnershipDBusProxy proxy;
  if (!proxy.Initialize()) {
    LOG(ERROR) << "Failed to start tpm ownership proxy";
    return false;
  }
  ::tpm_manager::GetTpmStatusRequest request;
  auto method = base::Bind(&::tpm_manager::TpmOwnershipDBusProxy::GetTpmStatus,
                           base::Unretained(&proxy), request);
  ::tpm_manager::GetTpmStatusReply reply;
  SendAndWait(method, &reply);
  if (reply.status() != ::tpm_manager::STATUS_SUCCESS) {
    LOG(ERROR) << "Failed to get tpm status.";
    puts(GetProtoDebugString(reply).c_str());
    return false;
  }

  if (!reply.has_version_info()) {
    LOG(ERROR) << "tpm status reply is missing version info.";
    return false;
  }

  version_info->family = reply.version_info().family();
  version_info->spec_level = reply.version_info().spec_level();
  version_info->manufacturer = reply.version_info().manufacturer();
  version_info->tpm_model = reply.version_info().tpm_model();
  version_info->firmware_version = reply.version_info().firmware_version();
  version_info->vendor_specific = reply.version_info().vendor_specific();
  return true;
}

}  // namespace tpm_manager

}  // namespace cryptohome
