// Copyright 2019 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/proxy/legacy_cryptohome_interface_adaptor.h"

#include <attestation-client-test/attestation/dbus-proxy-mocks.h>
#include <base/files/file_util.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/dbus/mock_dbus_method_response.h>
#include <chromeos/constants/cryptohome.h>
#include <tpm_manager-client-test/tpm_manager/dbus-proxy-mocks.h>

#include "cryptohome/mock_platform.h"
#include "user_data_auth/dbus-proxy-mocks.h"

namespace cryptohome {

namespace {

using ::brillo::dbus_utils::MockDBusMethodResponse;

using ::testing::_;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::InvokeArgument;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;

// A mock adaptor that is used for testing. This is added so that we can capture
// the Send*() functions used for sending signals.
class LegacyCryptohomeInterfaceAdaptorForTesting
    : public LegacyCryptohomeInterfaceAdaptor {
 public:
  LegacyCryptohomeInterfaceAdaptorForTesting(
      org::chromium::AttestationProxyInterface* attestation_proxy,
      org::chromium::TpmManagerProxyInterface* tpm_ownership_proxy,
      org::chromium::TpmNvramProxyInterface* tpm_nvram_proxy,
      org::chromium::UserDataAuthInterfaceProxyInterface* userdataauth_proxy,
      org::chromium::ArcQuotaProxyInterface* arc_quota_proxy,
      org::chromium::CryptohomePkcs11InterfaceProxyInterface* pkcs11_proxy,
      org::chromium::InstallAttributesInterfaceProxyInterface*
          install_attributes_proxy,
      org::chromium::CryptohomeMiscInterfaceProxyInterface* misc_proxy,
      cryptohome::Platform* platform)
      : LegacyCryptohomeInterfaceAdaptor(attestation_proxy,
                                         tpm_ownership_proxy,
                                         tpm_nvram_proxy,
                                         userdataauth_proxy,
                                         arc_quota_proxy,
                                         pkcs11_proxy,
                                         install_attributes_proxy,
                                         misc_proxy,
                                         platform) {}

  MOCK_METHOD(void,
              VirtualSendAsyncCallStatusSignal,
              (int32_t, bool, int32_t),
              (override));
  MOCK_METHOD(void,
              VirtualSendAsyncCallStatusWithDataSignal,
              (int32_t, bool, const std::vector<uint8_t>&),
              (override));
  MOCK_METHOD(void,
              VirtualSendDircryptoMigrationProgressSignal,
              (int32_t, uint64_t, uint64_t),
              (override));
  MOCK_METHOD(void, VirtualSendLowDiskSpaceSignal, (uint64_t), (override));
};

// Some common constants used for testing.
constexpr char kUsername1[] = "foo@gmail.com";
constexpr char kKeyLabel[] = "somelabel";
constexpr char kSecret[] = "blah";
constexpr char kSanitizedUsername1[] = "baadf00ddeadbeeffeedcafe";
constexpr char kPCARequest[] = "PCA\0Request\xFFMay\x80Have\0None.ASCII";
constexpr char kRequestOrigin[] = "SomeOrigin";

class LegacyCryptohomeInterfaceAdaptorTest : public ::testing::Test {
 public:
  LegacyCryptohomeInterfaceAdaptorTest() = default;
  LegacyCryptohomeInterfaceAdaptorTest(
      const LegacyCryptohomeInterfaceAdaptorTest&) = delete;
  LegacyCryptohomeInterfaceAdaptorTest& operator=(
      const LegacyCryptohomeInterfaceAdaptorTest&) = delete;

  ~LegacyCryptohomeInterfaceAdaptorTest() override = default;

  void SetUp() override {
    adaptor_.reset(new LegacyCryptohomeInterfaceAdaptorForTesting(
        &attestation_, &ownership_, &nvram_, &userdataauth_, &arc_quota_,
        &pkcs11_, &install_attributes_, &misc_, &platform_));

    account_.set_account_id(kUsername1);
    auth_.mutable_key()->set_secret(kSecret);
  }

 protected:
  // Mocks that will be passed into |adaptor_| for its internal use.
  NiceMock<org::chromium::AttestationProxyMock> attestation_;
  NiceMock<org::chromium::TpmManagerProxyMock> ownership_;
  NiceMock<org::chromium::TpmNvramProxyMock> nvram_;
  NiceMock<org::chromium::UserDataAuthInterfaceProxyMock> userdataauth_;
  NiceMock<org::chromium::ArcQuotaProxyMock> arc_quota_;
  NiceMock<org::chromium::CryptohomePkcs11InterfaceProxyMock> pkcs11_;
  NiceMock<org::chromium::InstallAttributesInterfaceProxyMock>
      install_attributes_;
  NiceMock<org::chromium::CryptohomeMiscInterfaceProxyMock> misc_;
  NiceMock<MockPlatform> platform_;

  // The adaptor that we'll be testing.
  std::unique_ptr<LegacyCryptohomeInterfaceAdaptorForTesting> adaptor_;

  // Default account identifier and authentication request set up with valid
  // value to avoid repeating the same pattern in many test.
  cryptohome::AccountIdentifier account_;
  cryptohome::AuthorizationRequest auth_;
};

// -------------------------- MountEx Related Tests --------------------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest, MountExSuccess) {
  cryptohome::MountRequest req;
  user_data_auth::MountRequest proxied_request;

  req.set_require_ephemeral(false);
  req.set_force_dircrypto_if_available(true);
  req.set_to_migrate_from_ecryptfs(false);
  req.set_public_mount(false);
  req.set_hidden_mount(false);

  EXPECT_CALL(userdataauth_, MountAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const user_data_auth::MountRequest& in_request,
                    const base::Callback<void(
                        const user_data_auth::MountReply&)>& success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            user_data_auth::MountReply proxied_reply;
            proxied_reply.set_recreated(true);
            proxied_reply.set_sanitized_username(kSanitizedUsername1);
            success_callback.Run(proxied_reply);
          })));

  base::Optional<cryptohome::BaseReply> final_reply;
  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  response->save_return_args(&final_reply);

  adaptor_->MountEx(std::move(response), account_, auth_, req);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(final_reply.has_value());

  // Verify its content
  EXPECT_EQ(cryptohome::CRYPTOHOME_ERROR_NOT_SET, final_reply->error());
  EXPECT_TRUE(final_reply->HasExtension(cryptohome::MountReply::reply));
  auto ext = final_reply->GetExtension(cryptohome::MountReply::reply);
  EXPECT_TRUE(ext.recreated());
  EXPECT_EQ(ext.sanitized_username(), kSanitizedUsername1);

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_EQ(proxied_request.account().account_id(), kUsername1);
  EXPECT_EQ(proxied_request.authorization().key().secret(), kSecret);
  EXPECT_FALSE(proxied_request.require_ephemeral());
  EXPECT_TRUE(proxied_request.force_dircrypto_if_available());
  EXPECT_FALSE(proxied_request.to_migrate_from_ecryptfs());
  EXPECT_FALSE(proxied_request.public_mount());
  EXPECT_FALSE(proxied_request.hidden_mount());
  EXPECT_FALSE(proxied_request.guest_mount());
  EXPECT_FALSE(proxied_request.has_create());
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest, MountExSuccessWithCreate) {
  cryptohome::MountRequest req;
  user_data_auth::MountRequest proxied_request;

  req.set_require_ephemeral(false);
  req.set_force_dircrypto_if_available(true);
  req.set_to_migrate_from_ecryptfs(false);
  req.set_public_mount(false);
  req.set_hidden_mount(false);
  req.mutable_create()->set_force_ecryptfs(true);
  req.mutable_create()->set_copy_authorization_key(true);
  auto key = req.mutable_create()->add_keys();
  key->set_secret(kSecret);

  EXPECT_CALL(userdataauth_, MountAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const user_data_auth::MountRequest& in_request,
                    const base::Callback<void(
                        const user_data_auth::MountReply&)>& success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            user_data_auth::MountReply proxied_reply;
            proxied_reply.set_recreated(true);
            proxied_reply.set_sanitized_username(kSanitizedUsername1);
            success_callback.Run(proxied_reply);
          })));

  int respond_count = 0;
  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  response->set_return_callback(base::Bind(
      [](int* respond_count_ptr, const cryptohome::BaseReply& reply) {
        EXPECT_EQ(cryptohome::CRYPTOHOME_ERROR_NOT_SET, reply.error());
        EXPECT_TRUE(reply.HasExtension(cryptohome::MountReply::reply));
        auto ext = reply.GetExtension(cryptohome::MountReply::reply);
        EXPECT_TRUE(ext.recreated());
        EXPECT_EQ(ext.sanitized_username(), kSanitizedUsername1);
        (*respond_count_ptr)++;
      },
      &respond_count));
  adaptor_->MountEx(std::move(response), account_, auth_, req);

  // Verify that Return() is indeed called.
  EXPECT_EQ(respond_count, 1);

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_EQ(proxied_request.account().account_id(), kUsername1);
  EXPECT_EQ(proxied_request.authorization().key().secret(), kSecret);
  EXPECT_FALSE(proxied_request.require_ephemeral());
  EXPECT_TRUE(proxied_request.force_dircrypto_if_available());
  EXPECT_FALSE(proxied_request.to_migrate_from_ecryptfs());
  EXPECT_FALSE(proxied_request.public_mount());
  EXPECT_FALSE(proxied_request.hidden_mount());
  EXPECT_FALSE(proxied_request.guest_mount());
  EXPECT_TRUE(proxied_request.has_create());
  EXPECT_TRUE(proxied_request.create().force_ecryptfs());
  EXPECT_TRUE(proxied_request.create().copy_authorization_key());
  EXPECT_EQ(proxied_request.create().keys_size(), 1);
  EXPECT_EQ(proxied_request.create().keys(0).secret(), kSecret);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest, MountExFail) {
  cryptohome::MountRequest req;
  user_data_auth::MountRequest proxied_request;

  req.set_require_ephemeral(true);
  req.set_force_dircrypto_if_available(false);
  req.set_to_migrate_from_ecryptfs(true);
  req.set_public_mount(true);
  req.set_hidden_mount(true);

  EXPECT_CALL(userdataauth_, MountAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const user_data_auth::MountRequest& in_request,
                    const base::Callback<void(
                        const user_data_auth::MountReply&)>& success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            user_data_auth::MountReply proxied_reply;
            proxied_reply.set_error(
                user_data_auth::CRYPTOHOME_ERROR_MOUNT_FATAL);
            proxied_reply.set_recreated(false);
            success_callback.Run(proxied_reply);
          })));

  base::Optional<cryptohome::BaseReply> final_reply;
  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  response->save_return_args(&final_reply);

  adaptor_->MountEx(std::move(response), account_, auth_, req);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(final_reply.has_value());

  // Verify its content
  EXPECT_EQ(cryptohome::CRYPTOHOME_ERROR_MOUNT_FATAL, final_reply->error());
  EXPECT_TRUE(final_reply->HasExtension(cryptohome::MountReply::reply));
  auto ext = final_reply->GetExtension(cryptohome::MountReply::reply);
  EXPECT_FALSE(ext.recreated());

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_EQ(proxied_request.account().account_id(), kUsername1);
  EXPECT_EQ(proxied_request.authorization().key().secret(), kSecret);
  EXPECT_TRUE(proxied_request.require_ephemeral());
  EXPECT_FALSE(proxied_request.force_dircrypto_if_available());
  EXPECT_TRUE(proxied_request.to_migrate_from_ecryptfs());
  EXPECT_TRUE(proxied_request.public_mount());
  EXPECT_TRUE(proxied_request.hidden_mount());
  EXPECT_FALSE(proxied_request.guest_mount());
}

// ------------- TpmIsAttestationPrepared Related Tests -------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmIsAttestationPreparedSuccessResultTrue) {
  attestation::GetEnrollmentPreparationsRequest proxied_request;
  EXPECT_CALL(attestation_, GetEnrollmentPreparationsAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const attestation::GetEnrollmentPreparationsRequest&
                        in_request,
                    const base::Callback<void(
                        const attestation::GetEnrollmentPreparationsReply&)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            attestation::GetEnrollmentPreparationsReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            (*proxied_reply.mutable_enrollment_preparations())[0] = true;
            (*proxied_reply.mutable_enrollment_preparations())[1] = false;
            success_callback.Run(proxied_reply);
          })));

  base::Optional<bool> result;
  std::unique_ptr<MockDBusMethodResponse<bool>> response(
      new MockDBusMethodResponse<bool>(nullptr));
  response->save_return_args(&result);

  adaptor_->TpmIsAttestationPrepared(std::move(response));

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result.has_value());

  // Verify response content.
  EXPECT_TRUE(result.value());
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmIsAttestationPreparedSuccessResultFalse) {
  attestation::GetEnrollmentPreparationsRequest proxied_request;
  EXPECT_CALL(attestation_, GetEnrollmentPreparationsAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const attestation::GetEnrollmentPreparationsRequest&
                        in_request,
                    const base::Callback<void(
                        const attestation::GetEnrollmentPreparationsReply&)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            attestation::GetEnrollmentPreparationsReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            (*proxied_reply.mutable_enrollment_preparations())[0] = false;
            (*proxied_reply.mutable_enrollment_preparations())[1] = false;
            success_callback.Run(proxied_reply);
          })));

  base::Optional<bool> result;
  std::unique_ptr<MockDBusMethodResponse<bool>> response(
      new MockDBusMethodResponse<bool>(nullptr));
  response->save_return_args(&result);

  adaptor_->TpmIsAttestationPrepared(std::move(response));

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result.has_value());

  // Verify response content.
  EXPECT_FALSE(result.value());
}

// --------- TpmAttestationGetEnrollmentPreparationsEx Related Tests ---------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmAttestationGetEnrollmentPreparationsExSuccess) {
  attestation::GetEnrollmentPreparationsRequest proxied_request;
  EXPECT_CALL(attestation_, GetEnrollmentPreparationsAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const attestation::GetEnrollmentPreparationsRequest&
                        in_request,
                    const base::Callback<void(
                        const attestation::GetEnrollmentPreparationsReply&)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            attestation::GetEnrollmentPreparationsReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            (*proxied_reply.mutable_enrollment_preparations())[0] = true;
            (*proxied_reply.mutable_enrollment_preparations())[1] = false;
            success_callback.Run(proxied_reply);
          })));

  base::Optional<cryptohome::BaseReply> result;
  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  response->save_return_args(&result);

  cryptohome::AttestationGetEnrollmentPreparationsRequest in_request;
  in_request.set_pca_type(1);
  adaptor_->TpmAttestationGetEnrollmentPreparationsEx(std::move(response),
                                                      in_request);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result.has_value());

  // Verify response content.
  EXPECT_EQ(result->error(), cryptohome::CRYPTOHOME_ERROR_NOT_SET);
  EXPECT_TRUE(
      result->HasExtension(AttestationGetEnrollmentPreparationsReply::reply));
  auto& ext =
      result->GetExtension(AttestationGetEnrollmentPreparationsReply::reply);
  EXPECT_EQ(ext.enrollment_preparations().size(), 2);
  ASSERT_TRUE(ext.enrollment_preparations().contains(0));
  EXPECT_TRUE(ext.enrollment_preparations().at(0));
  ASSERT_TRUE(ext.enrollment_preparations().contains(1));
  EXPECT_FALSE(ext.enrollment_preparations().at(1));

  // Check that the proxied request have the right ACA
  EXPECT_EQ(proxied_request.aca_type(), attestation::ACAType::TEST_ACA);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmAttestationGetEnrollmentPreparationsExInvalidACA) {
  // GetEnrollmentPreparationsAsync() shouldn't get called because the ACA
  // specified is invalid.
  EXPECT_CALL(attestation_, GetEnrollmentPreparationsAsync(_, _, _, _))
      .Times(0);

  base::Optional<cryptohome::BaseReply> result;
  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  response->save_return_args(&result);
  EXPECT_CALL(
      *response,
      ReplyWithError(_, brillo::errors::dbus::kDomain, DBUS_ERROR_NOT_SUPPORTED,
                     "Requested ACA type 99999 is not supported in "
                     "TpmAttestationGetEnrollmentPreparationsEx()"))
      .WillOnce(Return());
  cryptohome::AttestationGetEnrollmentPreparationsRequest in_request;
  in_request.set_pca_type(99999);
  adaptor_->TpmAttestationGetEnrollmentPreparationsEx(std::move(response),
                                                      in_request);

  // Verify that Return() is not called
  ASSERT_FALSE(result.has_value());
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmAttestationGetEnrollmentPreparationsExFailure) {
  attestation::GetEnrollmentPreparationsRequest proxied_request;
  EXPECT_CALL(attestation_, GetEnrollmentPreparationsAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const attestation::GetEnrollmentPreparationsRequest&
                        in_request,
                    const base::Callback<void(
                        const attestation::GetEnrollmentPreparationsReply&)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            attestation::GetEnrollmentPreparationsReply proxied_reply;
            proxied_reply.set_status(
                attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
            success_callback.Run(proxied_reply);
          })));

  base::Optional<cryptohome::BaseReply> result;
  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  response->save_return_args(&result);

  cryptohome::AttestationGetEnrollmentPreparationsRequest in_request;
  in_request.set_pca_type(1);
  adaptor_->TpmAttestationGetEnrollmentPreparationsEx(std::move(response),
                                                      in_request);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result.has_value());

  // Verify response content.
  EXPECT_EQ(result->error(),
            cryptohome::CRYPTOHOME_ERROR_INTERNAL_ATTESTATION_ERROR);

  // Check that the proxied request have the right ACA
  EXPECT_EQ(proxied_request.aca_type(), attestation::ACAType::TEST_ACA);
}

// ------------- TpmAttestationCreateEnrollRequest Related Tests -------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmAttestationCreateEnrollRequestSuccess) {
  attestation::CreateEnrollRequestRequest proxied_request;
  EXPECT_CALL(attestation_, CreateEnrollRequestAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const attestation::CreateEnrollRequestRequest& in_request,
                    const base::Callback<void(
                        const attestation::CreateEnrollRequestReply&)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            attestation::CreateEnrollRequestReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            proxied_reply.set_pca_request(
                std::string(kPCARequest, sizeof(kPCARequest)));
            success_callback.Run(proxied_reply);
          })));

  base::Optional<std::vector<uint8_t>> result_pca_request;
  std::unique_ptr<MockDBusMethodResponse<std::vector<uint8_t>>> response(
      new MockDBusMethodResponse<std::vector<uint8_t>>(nullptr));
  response->save_return_args(&result_pca_request);

  adaptor_->TpmAttestationCreateEnrollRequest(
      std::move(response), static_cast<int>(attestation::TEST_ACA));

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result_pca_request.has_value());

  // Verify response content.
  EXPECT_EQ(
      result_pca_request.value(),
      std::vector<uint8_t>(kPCARequest, kPCARequest + sizeof(kPCARequest)));

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_EQ(proxied_request.aca_type(), attestation::TEST_ACA);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmAttestationCreateEnrollRequestInvalidACA) {
  std::unique_ptr<MockDBusMethodResponse<std::vector<uint8_t>>> response(
      new MockDBusMethodResponse<std::vector<uint8_t>>(nullptr));
  EXPECT_CALL(
      *response,
      ReplyWithError(_, brillo::errors::dbus::kDomain, DBUS_ERROR_NOT_SUPPORTED,
                     "Requested ACA type 99999 is not supported"))
      .WillOnce(Return());

  // 99999 is an invalid ACA
  adaptor_->TpmAttestationCreateEnrollRequest(std::move(response), 99999);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmAttestationCreateEnrollRequestFailed) {
  attestation::CreateEnrollRequestRequest proxied_request;
  EXPECT_CALL(attestation_, CreateEnrollRequestAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const attestation::CreateEnrollRequestRequest& in_request,
                    const base::Callback<void(
                        const attestation::CreateEnrollRequestReply&)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            attestation::CreateEnrollRequestReply reply;
            reply.set_status(attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
            success_callback.Run(reply);
          })));

  std::unique_ptr<MockDBusMethodResponse<std::vector<uint8_t>>> response(
      new MockDBusMethodResponse<std::vector<uint8_t>>(nullptr));
  EXPECT_CALL(
      *response,
      ReplyWithError(_, brillo::errors::dbus::kDomain, DBUS_ERROR_FAILED,
                     "Attestation daemon returned status " +
                         std::to_string(static_cast<int>(
                             attestation::STATUS_UNEXPECTED_DEVICE_ERROR))))
      .WillOnce(Return());
  adaptor_->TpmAttestationCreateEnrollRequest(
      std::move(response), static_cast<int>(attestation::DEFAULT_ACA));

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_EQ(proxied_request.aca_type(), attestation::DEFAULT_ACA);
}

// ------------------- TpmAttestationEnroll Related Tests -------------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest, TpmAttestationEnrollSuccess) {
  attestation::FinishEnrollRequest proxied_request;
  EXPECT_CALL(attestation_, FinishEnrollAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke(
              [](const attestation::FinishEnrollRequest& in_request,
                 const base::Callback<void(
                     const attestation::FinishEnrollReply&)>& success_callback,
                 const base::Callback<void(brillo::Error*)>& error_callback,
                 int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
                attestation::FinishEnrollReply proxied_reply;
                proxied_reply.set_status(attestation::STATUS_SUCCESS);
                success_callback.Run(proxied_reply);
              })));

  base::Optional<bool> result_success;
  std::unique_ptr<MockDBusMethodResponse<bool>> response(
      new MockDBusMethodResponse<bool>(nullptr));
  response->save_return_args(&result_success);

  std::vector<uint8_t> pca_request(kPCARequest,
                                   kPCARequest + sizeof(kPCARequest));
  adaptor_->TpmAttestationEnroll(std::move(response),
                                 static_cast<int>(attestation::TEST_ACA),
                                 pca_request);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result_success.has_value());

  // Verify the response.
  EXPECT_TRUE(result_success.value());

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_EQ(proxied_request.aca_type(), attestation::TEST_ACA);
  EXPECT_EQ(proxied_request.pca_response(),
            std::string(kPCARequest, kPCARequest + sizeof(kPCARequest)));
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest, TpmAttestationEnrollInvalidACA) {
  std::unique_ptr<MockDBusMethodResponse<bool>> response(
      new MockDBusMethodResponse<bool>(nullptr));
  EXPECT_CALL(
      *response,
      ReplyWithError(_, brillo::errors::dbus::kDomain, DBUS_ERROR_NOT_SUPPORTED,
                     "Requested ACA type 99999 is not supported"))
      .WillOnce(Return());
  std::vector<uint8_t> pca_request(kPCARequest,
                                   kPCARequest + sizeof(kPCARequest));

  // 99999 is an invalid ACA
  adaptor_->TpmAttestationEnroll(std::move(response), 99999, pca_request);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest, TpmAttestationEnrollFailed) {
  attestation::FinishEnrollRequest proxied_request;
  EXPECT_CALL(attestation_, FinishEnrollAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke(
              [](const attestation::FinishEnrollRequest& in_request,
                 const base::Callback<void(
                     const attestation::FinishEnrollReply&)>& success_callback,
                 const base::Callback<void(brillo::Error*)>& error_callback,
                 int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
                attestation::FinishEnrollReply reply;
                reply.set_status(attestation::STATUS_NOT_READY);
                success_callback.Run(reply);
              })));

  base::Optional<bool> result_success;
  std::unique_ptr<MockDBusMethodResponse<bool>> response(
      new MockDBusMethodResponse<bool>(nullptr));
  response->save_return_args(&result_success);

  std::vector<uint8_t> pca_request(kPCARequest,
                                   kPCARequest + sizeof(kPCARequest));
  adaptor_->TpmAttestationEnroll(std::move(response),
                                 static_cast<int>(attestation::DEFAULT_ACA),
                                 pca_request);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result_success.has_value());

  // Verify the response.
  EXPECT_FALSE(result_success.value());

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_EQ(proxied_request.aca_type(), attestation::DEFAULT_ACA);
  EXPECT_EQ(proxied_request.pca_response(),
            std::string(kPCARequest, kPCARequest + sizeof(kPCARequest)));
}

// ------------- TpmAttestationCreateCertRequest Related Tests -------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmAttestationCreateCertRequestSuccess) {
  attestation::CreateCertificateRequestRequest proxied_request;
  EXPECT_CALL(attestation_, CreateCertificateRequestAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke(
              [](const attestation::CreateCertificateRequestRequest& in_request,
                 const base::Callback<void(
                     const attestation::CreateCertificateRequestReply&)>&
                     success_callback,
                 const base::Callback<void(brillo::Error*)>& error_callback,
                 int timeout_ms) {
                attestation::CreateCertificateRequestReply proxied_reply;
                proxied_reply.set_status(attestation::STATUS_SUCCESS);
                proxied_reply.set_pca_request(
                    std::string(kPCARequest, sizeof(kPCARequest)));
                success_callback.Run(proxied_reply);
              })));

  base::Optional<std::vector<uint8_t>> result_pca_request;
  std::unique_ptr<MockDBusMethodResponse<std::vector<uint8_t>>> response(
      new MockDBusMethodResponse<std::vector<uint8_t>>(nullptr));
  response->save_return_args(&result_pca_request);

  adaptor_->TpmAttestationCreateCertRequest(
      std::move(response), static_cast<int>(attestation::TEST_ACA),
      static_cast<int>(attestation::CONTENT_PROTECTION_CERTIFICATE), kUsername1,
      kRequestOrigin);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result_pca_request.has_value());

  // Verify response content.
  EXPECT_EQ(
      result_pca_request.value(),
      std::vector<uint8_t>(kPCARequest, kPCARequest + sizeof(kPCARequest)));

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_EQ(proxied_request.aca_type(), attestation::TEST_ACA);
  EXPECT_EQ(proxied_request.username(), kUsername1);
  EXPECT_EQ(proxied_request.request_origin(), kRequestOrigin);
  EXPECT_EQ(proxied_request.certificate_profile(),
            attestation::CONTENT_PROTECTION_CERTIFICATE);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmAttestationCreateCertRequestInvalidACA) {
  std::unique_ptr<MockDBusMethodResponse<std::vector<uint8_t>>> response(
      new MockDBusMethodResponse<std::vector<uint8_t>>(nullptr));
  EXPECT_CALL(
      *response,
      ReplyWithError(_, brillo::errors::dbus::kDomain, DBUS_ERROR_NOT_SUPPORTED,
                     "Requested ACA type 99999 is not supported"))
      .WillOnce(Return());

  // 99999 is an invalid ACA
  adaptor_->TpmAttestationCreateCertRequest(std::move(response), 99999, 2,
                                            kUsername1, kRequestOrigin);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmAttestationCreateCertRequestFailed) {
  attestation::CreateCertificateRequestRequest proxied_request;
  EXPECT_CALL(attestation_, CreateCertificateRequestAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke(
              [](const attestation::CreateCertificateRequestRequest& in_request,
                 const base::Callback<void(
                     const attestation::CreateCertificateRequestReply&)>&
                     success_callback,
                 const base::Callback<void(brillo::Error*)>& error_callback,
                 int timeout_ms) {
                attestation::CreateCertificateRequestReply reply;
                reply.set_status(attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
                success_callback.Run(reply);
              })));

  std::unique_ptr<MockDBusMethodResponse<std::vector<uint8_t>>> response(
      new MockDBusMethodResponse<std::vector<uint8_t>>(nullptr));
  EXPECT_CALL(
      *response,
      ReplyWithError(_, brillo::errors::dbus::kDomain, DBUS_ERROR_FAILED,
                     "Attestation daemon returned status " +
                         std::to_string(static_cast<int>(
                             attestation::STATUS_UNEXPECTED_DEVICE_ERROR))))
      .WillOnce(Return());

  // 12345 is an invalid certificate profile and should result in
  // ENTERPRISE_USER_CERTIFICATE.
  adaptor_->TpmAttestationCreateCertRequest(
      std::move(response), static_cast<int>(attestation::DEFAULT_ACA), 12345,
      kUsername1, kRequestOrigin);

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_EQ(proxied_request.aca_type(), attestation::DEFAULT_ACA);
  EXPECT_EQ(proxied_request.username(), kUsername1);
  EXPECT_EQ(proxied_request.request_origin(), kRequestOrigin);
  EXPECT_EQ(proxied_request.certificate_profile(),
            attestation::ENTERPRISE_USER_CERTIFICATE);
}

// ------------- TpmAttestationDeleteKey(s) Related Tests -------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest, TpmAttestationDeleteKeysSuccess) {
  attestation::DeleteKeysRequest proxied_request;
  EXPECT_CALL(attestation_, DeleteKeysAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const attestation::DeleteKeysRequest& in_request,
                    const base::Callback<void(
                        const attestation::DeleteKeysReply&)>& success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            attestation::DeleteKeysReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            success_callback.Run(proxied_reply);
          })));

  base::Optional<bool> result;
  std::unique_ptr<MockDBusMethodResponse<bool>> response(
      new MockDBusMethodResponse<bool>(nullptr));
  response->save_return_args(&result);

  adaptor_->TpmAttestationDeleteKeys(std::move(response),
                                     /*is_user_specific=*/true, kUsername1,
                                     kKeyLabel);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result.has_value());

  // Verify response content.
  EXPECT_TRUE(result.value());

  // Verify that the parameters passed to DBus Proxy (New interface) are
  // correct.
  EXPECT_EQ(proxied_request.username(), kUsername1);
  EXPECT_EQ(proxied_request.key_label_match(), kKeyLabel);
  EXPECT_EQ(proxied_request.match_behavior(),
            attestation::DeleteKeysRequest::MATCH_BEHAVIOR_PREFIX);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest, TpmAttestationDeleteKeySuccess) {
  attestation::DeleteKeysRequest proxied_request;
  EXPECT_CALL(attestation_, DeleteKeysAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const attestation::DeleteKeysRequest& in_request,
                    const base::Callback<void(
                        const attestation::DeleteKeysReply&)>& success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
            attestation::DeleteKeysReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            success_callback.Run(proxied_reply);
          })));

  base::Optional<bool> result;
  std::unique_ptr<MockDBusMethodResponse<bool>> response(
      new MockDBusMethodResponse<bool>(nullptr));
  response->save_return_args(&result);

  adaptor_->TpmAttestationDeleteKey(std::move(response),
                                    /*is_user_specific=*/true, kUsername1,
                                    kKeyLabel);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(result.has_value());

  // Verify response content.
  EXPECT_TRUE(result.value());

  // Verify that the parameters passed to DBus Proxy (New interface) are
  // correct.
  EXPECT_EQ(proxied_request.username(), kUsername1);
  EXPECT_EQ(proxied_request.key_label_match(), kKeyLabel);
  EXPECT_EQ(proxied_request.match_behavior(),
            attestation::DeleteKeysRequest::MATCH_BEHAVIOR_EXACT);
}

// -------------------- MigrateToDircrypto Related Tests --------------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest, MigrateToDircryptoSuccess) {
  // Note that failure case is NOT tested because this method does not return
  // anything so the failure case is no different from the success case.

  user_data_auth::StartMigrateToDircryptoRequest proxied_request;
  EXPECT_CALL(userdataauth_, StartMigrateToDircryptoAsync(_, _, _, _))
      .WillOnce(DoAll(
          SaveArg<0>(&proxied_request),
          Invoke([](const user_data_auth::StartMigrateToDircryptoRequest&
                        in_request,
                    const base::Callback<void(
                        const user_data_auth::StartMigrateToDircryptoReply&)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
            user_data_auth::StartMigrateToDircryptoReply proxied_reply;
            proxied_reply.set_error(user_data_auth::CRYPTOHOME_ERROR_NOT_SET);
            success_callback.Run(proxied_reply);
          })));

  bool called = false;
  std::unique_ptr<MockDBusMethodResponse<>> response(
      new MockDBusMethodResponse<>(nullptr));
  response->set_return_callback(base::Bind(
      [](bool* called_ptr) {
        // Return can only be called once
        ASSERT_FALSE(*called_ptr);
        *called_ptr = true;
      },
      &called));

  MigrateToDircryptoRequest request;
  request.set_minimal_migration(true);
  adaptor_->MigrateToDircrypto(std::move(response), account_, request);

  // Verify that Return() is indeed called at least once.
  ASSERT_TRUE(called);

  // Verify that the parameters passed to DBus Proxy (New interface) is correct.
  EXPECT_TRUE(proxied_request.minimal_migration());
  EXPECT_EQ(proxied_request.account_id().account_id(), kUsername1);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       DircryptoMigrationProgressSignalValidity) {
  constexpr uint64_t kCurrentBytes = 1234567890123ULL;
  constexpr uint64_t kTotalBytes = 9876543210987ULL;
  static_assert(kTotalBytes > kCurrentBytes,
                "Incorrect constant test values in "
                "DircryptoMigrationProgressSignalValidity");

  user_data_auth::DircryptoMigrationProgress progress;
  progress.set_status(user_data_auth::DIRCRYPTO_MIGRATION_SUCCESS);
  progress.set_current_bytes(kCurrentBytes);
  progress.set_total_bytes(kTotalBytes);

  EXPECT_CALL(*adaptor_,
              VirtualSendDircryptoMigrationProgressSignal(
                  DIRCRYPTO_MIGRATION_SUCCESS, kCurrentBytes, kTotalBytes))
      .WillOnce(Return());

  adaptor_->OnDircryptoMigrationProgressSignalForTestingOnly(progress);
}

// -------------------- LowDiskSpace Signal Related Tests --------------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest, LowDiskSpaceSignalValidity) {
  constexpr uint64_t kFreeDiskSpace = 998877665544ULL;

  user_data_auth::LowDiskSpace payload;
  payload.set_disk_free_bytes(kFreeDiskSpace);

  EXPECT_CALL(*adaptor_, VirtualSendLowDiskSpaceSignal(kFreeDiskSpace))
      .WillOnce(Return());

  adaptor_->OnLowDiskSpaceSignalForTestingOnly(payload);
}

// --------------- TPM Ownership Interface Related Tests ---------------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest, GetVersionInfo) {
  EXPECT_CALL(ownership_, GetVersionInfoAsync(_, _, _, _))
      .WillOnce(
          Invoke([](const tpm_manager::GetVersionInfoRequest& in_request,
                    const base::Callback<void(
                        const tpm_manager::GetVersionInfoReply& /*reply*/)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>&
                    /* error_callback */,
                    int /* timeout_ms */) {
            tpm_manager::GetVersionInfoReply info;
            info.set_family(1);
            info.set_spec_level(2);
            info.set_manufacturer(3);
            info.set_tpm_model(4);
            info.set_firmware_version(5);
            info.set_vendor_specific("ab");
            success_callback.Run(info);
          }));

  using VersionInfoResponse =
      MockDBusMethodResponse<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t,
                             std::string>;
  std::unique_ptr<VersionInfoResponse> response =
      std::make_unique<VersionInfoResponse>(nullptr);

  base::Optional<uint32_t> family;
  base::Optional<uint64_t> spec_level;
  base::Optional<uint32_t> manufacture;
  base::Optional<uint32_t> tpm_model;
  base::Optional<uint64_t> firmware_version;
  base::Optional<std::string> vendor_specific;
  response->save_return_args(&family, &spec_level, &manufacture, &tpm_model,
                             &firmware_version, &vendor_specific);

  adaptor_->TpmGetVersionStructured(std::move(response));

  EXPECT_TRUE(family.has_value());
  EXPECT_EQ(*family, 1);
  EXPECT_TRUE(spec_level.has_value());
  EXPECT_EQ(*spec_level, 2);
  EXPECT_TRUE(manufacture.has_value());
  EXPECT_EQ(*manufacture, 3);
  EXPECT_TRUE(tpm_model.has_value());
  EXPECT_EQ(*tpm_model, 4);
  EXPECT_TRUE(firmware_version.has_value());
  EXPECT_EQ(*firmware_version, 5);
  EXPECT_TRUE(vendor_specific.has_value());
  EXPECT_EQ(*vendor_specific, base::HexEncode("ab", 2));
}

// --------- CryptohomeMiscInterfaceProxyInterface Related Tests ---------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest, GetLoginStatus) {
  EXPECT_CALL(misc_, GetLoginStatusAsync(_, _, _, _))
      .WillOnce(
          Invoke([](const user_data_auth::GetLoginStatusRequest& request,
                    const base::Callback<void(
                        const user_data_auth::GetLoginStatusReply& /*reply*/)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>&
                    /* error_callback */,
                    int /* timeout_ms */) {
            user_data_auth::GetLoginStatusReply reply;
            reply.set_owner_user_exists(true);
            reply.set_is_locked_to_single_user(true);
            success_callback.Run(reply);
          }));

  base::Optional<cryptohome::BaseReply> final_reply;

  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  EXPECT_CALL(*response, ReplyWithError(_)).Times(0);
  EXPECT_CALL(*response, ReplyWithError(_, _, _, _)).Times(0);
  response->save_return_args(&final_reply);

  const cryptohome::GetLoginStatusRequest in_request;
  adaptor_->GetLoginStatus(std::move(response), in_request);

  ASSERT_TRUE(final_reply.has_value());
  ASSERT_TRUE(
      final_reply->HasExtension(cryptohome::GetLoginStatusReply::reply));
  const auto& ext =
      final_reply->GetExtension(cryptohome::GetLoginStatusReply::reply);

  // These are the default values when call to retrieve attestation status
  // failed.
  EXPECT_TRUE(ext.owner_user_exists());
  EXPECT_TRUE(ext.is_locked_to_single_user());
  EXPECT_FALSE(ext.boot_lockbox_finalized());
}

// This class holds the various extra setups to facilitate testing GetTpmStatus
class LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus
    : public LegacyCryptohomeInterfaceAdaptorTest {
 public:
  LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus() = default;
  LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus(
      const LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus&) = delete;
  LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus& operator=(
      const LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus&) = delete;

  ~LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus() override = default;

 protected:
  void SetUp() override {
    LegacyCryptohomeInterfaceAdaptorTest::SetUp();

    status_reply_.set_enabled(true);
    status_reply_.set_owned(true);
    status_reply_.mutable_local_data()->set_owner_password(kPassword);

    da_reply_.set_dictionary_attack_counter(kDACounter);
    da_reply_.set_dictionary_attack_threshold(kDAThreshold);
    da_reply_.set_dictionary_attack_lockout_in_effect(false);
    da_reply_.set_dictionary_attack_lockout_seconds_remaining(kDALockoutRem);

    install_attr_reply_.set_state(
        user_data_auth::InstallAttributesState::VALID);

    attestation_reply_.set_prepared_for_enrollment(true);
    attestation_reply_.set_enrolled(true);
    attestation_reply_.set_verified_boot(true);
    auto* identity1 = attestation_reply_.mutable_identities()->Add();
    identity1->set_features(kFeature1);
    auto* identity2 = attestation_reply_.mutable_identities()->Add();
    identity2->set_features(kFeature2);

    attestation::GetStatusReply::IdentityCertificate identity_cert1;
    identity_cert1.set_identity(kFeature1);
    identity_cert1.set_aca(kACA1);
    attestation_reply_.mutable_identity_certificates()->insert(
        google::protobuf::Map<
            int, attestation::GetStatusReply::IdentityCertificate>::
            value_type(kACA1, identity_cert1));

    attestation::GetStatusReply::IdentityCertificate identity_cert2;
    identity_cert2.set_identity(kFeature2);
    identity_cert2.set_aca(kACA2);
    attestation_reply_.mutable_identity_certificates()->insert(
        google::protobuf::Map<
            int, attestation::GetStatusReply::IdentityCertificate>::
            value_type(kACA2, identity_cert2));
  }

  void ExpectGetTpmStatus(
      const base::Optional<tpm_manager::GetTpmStatusReply>& reply) {
    EXPECT_CALL(ownership_, GetTpmStatusAsync(_, _, _, _))
        .WillOnce(Invoke(
            [reply](const tpm_manager::GetTpmStatusRequest& in_request,
                    const base::Callback<void(
                        const tpm_manager::GetTpmStatusReply& /*reply*/)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
              if (reply.has_value()) {
                // If |reply| has value, then the method will be successful and
                // |reply| will be returned.
                success_callback.Run(reply.value());
              } else {
                // If not, the method will return an error.
                error_callback.Run(CreateDefaultError(FROM_HERE).get());
              }
            }));
  }

  void ExpectGetDictionaryAttackInfo(
      const base::Optional<tpm_manager::GetDictionaryAttackInfoReply>& reply) {
    EXPECT_CALL(ownership_, GetDictionaryAttackInfoAsync(_, _, _, _))
        .WillOnce(Invoke(
            [reply](
                const tpm_manager::GetDictionaryAttackInfoRequest& in_request,
                const base::Callback<void(
                    const tpm_manager::
                        GetDictionaryAttackInfoReply& /*reply*/)>&
                    success_callback,
                const base::Callback<void(brillo::Error*)>& error_callback,
                int timeout_ms) {
              if (reply.has_value()) {
                success_callback.Run(reply.value());
              } else {
                error_callback.Run(CreateDefaultError(FROM_HERE).get());
              }
            }));
  }

  void ExpectInstallAttributesGetStatus(
      const base::Optional<user_data_auth::InstallAttributesGetStatusReply>&
          reply) {
    EXPECT_CALL(install_attributes_,
                InstallAttributesGetStatusAsync(_, _, _, _))
        .WillOnce(Invoke(
            [reply](const user_data_auth::InstallAttributesGetStatusRequest&
                        in_request,
                    const base::Callback<void(
                        const user_data_auth::
                            InstallAttributesGetStatusReply& /*reply*/)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
              if (reply.has_value()) {
                success_callback.Run(reply.value());
              } else {
                error_callback.Run(CreateDefaultError(FROM_HERE).get());
              }
            }));
  }

  void ExpectAttestationGetStatus(
      const base::Optional<attestation::GetStatusReply>& reply) {
    EXPECT_CALL(attestation_, GetStatusAsync(_, _, _, _))
        .WillOnce(Invoke(
            [reply](const attestation::GetStatusRequest& in_request,
                    const base::Callback<void(
                        const attestation::GetStatusReply& /*reply*/)>&
                        success_callback,
                    const base::Callback<void(brillo::Error*)>& error_callback,
                    int timeout_ms) {
              if (reply.has_value()) {
                success_callback.Run(reply.value());
              } else {
                error_callback.Run(CreateDefaultError(FROM_HERE).get());
              }
            }));
  }

  // The reply we'll get from various proxies.
  tpm_manager::GetTpmStatusReply status_reply_;
  tpm_manager::GetDictionaryAttackInfoReply da_reply_;
  user_data_auth::InstallAttributesGetStatusReply install_attr_reply_;
  attestation::GetStatusReply attestation_reply_;

  // The request we send to GetTpmStatus()
  cryptohome::GetTpmStatusRequest in_request_;

  // Constants used during testing
  static constexpr char kPassword[] = "YetAnotherPassword";
  static constexpr int kDACounter = 42;      // The answer
  static constexpr int kDAThreshold = 4200;  // 100x The answer!!
  static constexpr int kDALockoutRem = 0;
  static constexpr int kFeature1 = 0xDEADBEEF;
  static constexpr int kFeature2 = 0xBAADF00D;
  static constexpr int kACA1 = 1;
  static constexpr int kACA2 = 2;

 private:
  static brillo::ErrorPtr CreateDefaultError(const base::Location& from_here) {
    brillo::ErrorPtr error;
    brillo::Error::AddTo(&error, from_here, brillo::errors::dbus::kDomain,
                         DBUS_ERROR_FAILED, "Here's a fake error");
    return error;
  }
};

constexpr char LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus::kPassword[];
constexpr int LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus::kDACounter;
constexpr int LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus::kDAThreshold;
constexpr int
    LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus::kDALockoutRem;
constexpr int LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus::kFeature1;
constexpr int LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus::kFeature2;
constexpr int LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus::kACA1;
constexpr int LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus::kACA2;

TEST_F(LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus,
       GetTpmStatusValidity) {
  // Setup GetTpmStatus in tpm_manager to successfully return |status_reply_|
  ExpectGetTpmStatus(status_reply_);
  // Setup GetDictionaryAttackInfo in tpm_manager to successfully return
  // |da_reply_|
  ExpectGetDictionaryAttackInfo(da_reply_);
  // Setup GetStatus in cryptohome/install attributes interface to sucessfully
  // return |install_attr_reply_|
  ExpectInstallAttributesGetStatus(install_attr_reply_);
  // Setup GetStatus in attestation to successfully return |attestation_reply_|
  ExpectAttestationGetStatus(attestation_reply_);

  EXPECT_CALL(platform_,
              FileExists(base::FilePath(cryptohome::kLockedToSingleUserFile)))
      .WillOnce(Return(true));

  base::Optional<cryptohome::BaseReply> final_reply;

  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  EXPECT_CALL(*response, ReplyWithError(_)).Times(0);
  EXPECT_CALL(*response, ReplyWithError(_, _, _, _)).Times(0);
  response->save_return_args(&final_reply);

  adaptor_->GetTpmStatus(std::move(response), in_request_);

  ASSERT_TRUE(final_reply.has_value());
  ASSERT_TRUE(final_reply->HasExtension(cryptohome::GetTpmStatusReply::reply));
  const auto& ext =
      final_reply->GetExtension(cryptohome::GetTpmStatusReply::reply);

  EXPECT_EQ(ext.enabled(), status_reply_.enabled());
  EXPECT_EQ(ext.owned(), status_reply_.owned());
  // |initialized| should be false because the owner password is supplied in
  // |status_reply_|.
  EXPECT_FALSE(ext.initialized());
  EXPECT_EQ(ext.owner_password(), status_reply_.local_data().owner_password());

  EXPECT_EQ(ext.dictionary_attack_counter(),
            da_reply_.dictionary_attack_counter());
  EXPECT_EQ(ext.dictionary_attack_threshold(),
            da_reply_.dictionary_attack_threshold());
  EXPECT_EQ(ext.dictionary_attack_lockout_in_effect(),
            da_reply_.dictionary_attack_lockout_in_effect());
  EXPECT_EQ(ext.dictionary_attack_lockout_seconds_remaining(),
            da_reply_.dictionary_attack_lockout_seconds_remaining());

  // |install_lockbox_finalized| is true because |install_attr_reply_.state()|
  // is VALID.
  EXPECT_TRUE(ext.install_lockbox_finalized());
  // |ext.boot_lockbox_finalized| is deprecated and always set to false.
  EXPECT_FALSE(ext.boot_lockbox_finalized());
  // |ext.is_locked_to_single_user| is set according to the flag file specified
  // in kLockedToSingleUserFile.
  EXPECT_TRUE(ext.is_locked_to_single_user());

  EXPECT_EQ(ext.attestation_prepared(),
            attestation_reply_.prepared_for_enrollment());
  EXPECT_EQ(ext.attestation_enrolled(), attestation_reply_.enrolled());
  EXPECT_EQ(ext.verified_boot_measured(), attestation_reply_.verified_boot());

  EXPECT_EQ(ext.identities().size(), attestation_reply_.identities().size());
  EXPECT_EQ(ext.identities().Get(0).features(),
            attestation_reply_.identities().Get(0).features());
  EXPECT_EQ(ext.identities().Get(1).features(),
            attestation_reply_.identities().Get(1).features());

  EXPECT_EQ(ext.identity_certificates().size(),
            attestation_reply_.identity_certificates().size());
  EXPECT_EQ(ext.identity_certificates().count(kACA1), 1);
  EXPECT_EQ(ext.identity_certificates().at(kACA1).identity(),
            attestation_reply_.identity_certificates().at(kACA1).identity());
  EXPECT_EQ(ext.identity_certificates().at(kACA1).aca(),
            attestation_reply_.identity_certificates().at(kACA1).aca());
  EXPECT_EQ(ext.identity_certificates().count(kACA2), 1);
  EXPECT_EQ(ext.identity_certificates().at(kACA2).identity(),
            attestation_reply_.identity_certificates().at(kACA2).identity());
  EXPECT_EQ(ext.identity_certificates().at(kACA2).aca(),
            attestation_reply_.identity_certificates().at(kACA2).aca());
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus,
       GetTpmStatusInitialized) {
  // If it's owned and no there's no owner_password, then it's initialized.
  status_reply_.mutable_local_data()->clear_owner_password();

  // Setup GetTpmStatus in tpm_manager to successfully return |status_reply_|
  ExpectGetTpmStatus(status_reply_);
  // Setup GetDictionaryAttackInfo in tpm_manager to successfully return
  // |da_reply_|
  ExpectGetDictionaryAttackInfo(da_reply_);
  // Setup GetStatus in cryptohome/install attributes interface to sucessfully
  // return |install_attr_reply_|
  ExpectInstallAttributesGetStatus(install_attr_reply_);
  // Setup GetStatus in attestation to successfully return |attestation_reply_|
  ExpectAttestationGetStatus(attestation_reply_);

  EXPECT_CALL(platform_,
              FileExists(base::FilePath(cryptohome::kLockedToSingleUserFile)))
      .WillOnce(Return(false));

  base::Optional<cryptohome::BaseReply> final_reply;

  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  EXPECT_CALL(*response, ReplyWithError(_)).Times(0);
  EXPECT_CALL(*response, ReplyWithError(_, _, _, _)).Times(0);
  response->save_return_args(&final_reply);

  adaptor_->GetTpmStatus(std::move(response), in_request_);

  ASSERT_TRUE(final_reply.has_value());
  ASSERT_TRUE(final_reply->HasExtension(cryptohome::GetTpmStatusReply::reply));
  const auto& ext =
      final_reply->GetExtension(cryptohome::GetTpmStatusReply::reply);

  // |initialized| is set to true because owner_password is cleared but owned is
  // true.
  EXPECT_TRUE(ext.initialized());
  EXPECT_EQ(ext.owner_password(), status_reply_.local_data().owner_password());

  EXPECT_FALSE(ext.is_locked_to_single_user());
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus,
       GetTpmStatusStageOwnershipStatusFail) {
  status_reply_.set_status(tpm_manager::STATUS_DEVICE_ERROR);

  // Setup GetTpmStatus in tpm_manager to successfully return |status_reply_|
  ExpectGetTpmStatus(status_reply_);

  base::Optional<cryptohome::BaseReply> final_reply;

  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  EXPECT_CALL(*response, ReplyWithError(_, _, _, _)).WillOnce(Return());
  response->save_return_args(&final_reply);

  adaptor_->GetTpmStatus(std::move(response), in_request_);

  ASSERT_FALSE(final_reply.has_value());
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus,
       GetTpmStatusStageDictionaryAttackFail) {
  da_reply_.set_status(tpm_manager::STATUS_DEVICE_ERROR);

  // Setup GetTpmStatus in tpm_manager to successfully return |status_reply_|
  ExpectGetTpmStatus(status_reply_);
  // Setup GetDictionaryAttackInfo in tpm_manager to successfully return
  // |da_reply_|
  ExpectGetDictionaryAttackInfo(da_reply_);
  // Setup GetStatus in cryptohome/install attributes interface to sucessfully
  // return |install_attr_reply_|
  ExpectInstallAttributesGetStatus(install_attr_reply_);
  // Setup GetStatus in attestation to successfully return |attestation_reply_|
  ExpectAttestationGetStatus(attestation_reply_);

  base::Optional<cryptohome::BaseReply> final_reply;

  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  EXPECT_CALL(*response, ReplyWithError(_)).Times(0);
  EXPECT_CALL(*response, ReplyWithError(_, _, _, _)).Times(0);
  response->save_return_args(&final_reply);

  adaptor_->GetTpmStatus(std::move(response), in_request_);

  ASSERT_TRUE(final_reply.has_value());
  ASSERT_TRUE(final_reply->HasExtension(cryptohome::GetTpmStatusReply::reply));
  const auto& ext =
      final_reply->GetExtension(cryptohome::GetTpmStatusReply::reply);

  // These are the default values when call to retrieve DictionaryAttack info
  // failed.
  EXPECT_EQ(ext.dictionary_attack_counter(), 0);
  EXPECT_EQ(ext.dictionary_attack_threshold(), 0);
  EXPECT_FALSE(ext.dictionary_attack_lockout_in_effect());
  EXPECT_EQ(ext.dictionary_attack_lockout_seconds_remaining(), 0);
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus,
       GetTpmStatusStageInstallAttributesFail) {
  install_attr_reply_.set_error(
      user_data_auth::CRYPTOHOME_ERROR_INVALID_ARGUMENT);

  // Setup GetTpmStatus in tpm_manager to successfully return |status_reply_|
  ExpectGetTpmStatus(status_reply_);
  // Setup GetDictionaryAttackInfo in tpm_manager to successfully return
  // |da_reply_|
  ExpectGetDictionaryAttackInfo(da_reply_);
  // Setup GetStatus in cryptohome/install attributes interface to sucessfully
  // return |install_attr_reply_|
  ExpectInstallAttributesGetStatus(install_attr_reply_);

  base::Optional<cryptohome::BaseReply> final_reply;

  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  EXPECT_CALL(*response, ReplyWithError(_, _, _, _)).WillOnce(Return());
  response->save_return_args(&final_reply);

  adaptor_->GetTpmStatus(std::move(response), in_request_);

  ASSERT_FALSE(final_reply.has_value());
}

TEST_F(LegacyCryptohomeInterfaceAdaptorTestForGetTpmStatus,
       GetTpmStatusStageAttestationFail) {
  attestation_reply_.set_status(attestation::STATUS_NOT_AVAILABLE);

  // Setup GetTpmStatus in tpm_manager to successfully return |status_reply_|
  ExpectGetTpmStatus(status_reply_);
  // Setup GetDictionaryAttackInfo in tpm_manager to successfully return
  // |da_reply_|
  ExpectGetDictionaryAttackInfo(da_reply_);
  // Setup GetStatus in cryptohome/install attributes interface to sucessfully
  // return |install_attr_reply_|
  ExpectInstallAttributesGetStatus(install_attr_reply_);
  // Setup GetStatus in attestation to successfully return |attestation_reply_|
  ExpectAttestationGetStatus(attestation_reply_);

  base::Optional<cryptohome::BaseReply> final_reply;

  std::unique_ptr<MockDBusMethodResponse<cryptohome::BaseReply>> response(
      new MockDBusMethodResponse<cryptohome::BaseReply>(nullptr));
  EXPECT_CALL(*response, ReplyWithError(_)).Times(0);
  EXPECT_CALL(*response, ReplyWithError(_, _, _, _)).Times(0);
  response->save_return_args(&final_reply);

  adaptor_->GetTpmStatus(std::move(response), in_request_);

  ASSERT_TRUE(final_reply.has_value());
  ASSERT_TRUE(final_reply->HasExtension(cryptohome::GetTpmStatusReply::reply));
  const auto& ext =
      final_reply->GetExtension(cryptohome::GetTpmStatusReply::reply);

  // These are the default values when call to retrieve attestation status
  // failed.
  EXPECT_FALSE(ext.attestation_prepared());
  EXPECT_FALSE(ext.attestation_enrolled());
  EXPECT_FALSE(ext.verified_boot_measured());
}

}  // namespace

}  // namespace cryptohome
