// 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);

  EXPECT_CALL(userdataauth_, MountAsync(_, _, _, _))
      .WillOnce(
          Invoke([&](const user_data_auth::MountRequest& in_request,
                     base::OnceCallback<void(const user_data_auth::MountReply&)>
                         success_callback,
                     base::OnceCallback<void(brillo::Error*)> error_callback,
                     int timeout_ms) {
            proxied_request = in_request;
            user_data_auth::MountReply proxied_reply;
            proxied_reply.set_recreated(true);
            proxied_reply.set_sanitized_username(kSanitizedUsername1);
            std::move(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.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.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(
          Invoke([&](const user_data_auth::MountRequest& in_request,
                     base::OnceCallback<void(const user_data_auth::MountReply&)>
                         success_callback,
                     base::OnceCallback<void(brillo::Error*)> error_callback,
                     int timeout_ms) {
            proxied_request = in_request;
            user_data_auth::MountReply proxied_reply;
            proxied_reply.set_recreated(true);
            proxied_reply.set_sanitized_username(kSanitizedUsername1);
            std::move(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.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);

  EXPECT_CALL(userdataauth_, MountAsync(_, _, _, _))
      .WillOnce(
          Invoke([&](const user_data_auth::MountRequest& in_request,
                     base::OnceCallback<void(const user_data_auth::MountReply&)>
                         success_callback,
                     base::OnceCallback<void(brillo::Error*)> error_callback,
                     int timeout_ms) {
            proxied_request = in_request;
            user_data_auth::MountReply proxied_reply;
            proxied_reply.set_error(
                user_data_auth::CRYPTOHOME_ERROR_MOUNT_FATAL);
            proxied_reply.set_recreated(false);
            std::move(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_FALSE(proxied_request.guest_mount());
}

// ------------- TpmIsAttestationPrepared Related Tests -------------
TEST_F(LegacyCryptohomeInterfaceAdaptorTest,
       TpmIsAttestationPreparedSuccessResultTrue) {
  attestation::GetEnrollmentPreparationsRequest proxied_request;
  EXPECT_CALL(attestation_, GetEnrollmentPreparationsAsync(_, _, _, _))
      .WillOnce(Invoke(
          [&](const attestation::GetEnrollmentPreparationsRequest& in_request,
              base::OnceCallback<void(
                  const attestation::GetEnrollmentPreparationsReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms) {
            proxied_request = in_request;
            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;
            std::move(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(Invoke(
          [&](const attestation::GetEnrollmentPreparationsRequest& in_request,
              base::OnceCallback<void(
                  const attestation::GetEnrollmentPreparationsReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms) {
            proxied_request = in_request;
            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;
            std::move(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(Invoke(
          [&](const attestation::GetEnrollmentPreparationsRequest& in_request,
              base::OnceCallback<void(
                  const attestation::GetEnrollmentPreparationsReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms) {
            proxied_request = in_request;
            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;
            std::move(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(Invoke(
          [&](const attestation::GetEnrollmentPreparationsRequest& in_request,
              base::OnceCallback<void(
                  const attestation::GetEnrollmentPreparationsReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms) {
            proxied_request = in_request;
            attestation::GetEnrollmentPreparationsReply proxied_reply;
            proxied_reply.set_status(
                attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
            std::move(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(
          Invoke([&](const attestation::CreateEnrollRequestRequest& in_request,
                     base::OnceCallback<void(
                         const attestation::CreateEnrollRequestReply&)>
                         success_callback,
                     base::OnceCallback<void(brillo::Error*)> error_callback,
                     int timeout_ms) {
            proxied_request = in_request;
            attestation::CreateEnrollRequestReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            proxied_reply.set_pca_request(
                std::string(kPCARequest, sizeof(kPCARequest)));
            std::move(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(
          Invoke([&](const attestation::CreateEnrollRequestRequest& in_request,
                     base::OnceCallback<void(
                         const attestation::CreateEnrollRequestReply&)>
                         success_callback,
                     base::OnceCallback<void(brillo::Error*)> error_callback,
                     int timeout_ms) {
            proxied_request = in_request;
            attestation::CreateEnrollRequestReply reply;
            reply.set_status(attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
            std::move(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(Invoke(
          [&](const attestation::FinishEnrollRequest& in_request,
              base::OnceCallback<void(const attestation::FinishEnrollReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
            proxied_request = in_request;
            attestation::FinishEnrollReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            std::move(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(Invoke(
          [&](const attestation::FinishEnrollRequest& in_request,
              base::OnceCallback<void(const attestation::FinishEnrollReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
            proxied_request = in_request;
            attestation::FinishEnrollReply reply;
            reply.set_status(attestation::STATUS_NOT_READY);
            std::move(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(Invoke(
          [&](const attestation::CreateCertificateRequestRequest& in_request,
              base::OnceCallback<void(
                  const attestation::CreateCertificateRequestReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms) {
            proxied_request = in_request;
            attestation::CreateCertificateRequestReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            proxied_reply.set_pca_request(
                std::string(kPCARequest, sizeof(kPCARequest)));
            std::move(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(Invoke(
          [&](const attestation::CreateCertificateRequestRequest& in_request,
              base::OnceCallback<void(
                  const attestation::CreateCertificateRequestReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms) {
            proxied_request = in_request;
            attestation::CreateCertificateRequestReply reply;
            reply.set_status(attestation::STATUS_UNEXPECTED_DEVICE_ERROR);
            std::move(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(Invoke(
          [&](const attestation::DeleteKeysRequest& in_request,
              base::OnceCallback<void(const attestation::DeleteKeysReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms) {
            proxied_request = in_request;
            attestation::DeleteKeysReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            std::move(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(Invoke(
          [&](const attestation::DeleteKeysRequest& in_request,
              base::OnceCallback<void(const attestation::DeleteKeysReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms) {
            proxied_request = in_request;
            attestation::DeleteKeysReply proxied_reply;
            proxied_reply.set_status(attestation::STATUS_SUCCESS);
            std::move(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(Invoke(
          [&](const user_data_auth::StartMigrateToDircryptoRequest& in_request,
              base::OnceCallback<void(
                  const user_data_auth::StartMigrateToDircryptoReply&)>
                  success_callback,
              base::OnceCallback<void(brillo::Error*)> error_callback,
              int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
            proxied_request = in_request;
            user_data_auth::StartMigrateToDircryptoReply proxied_reply;
            proxied_reply.set_error(user_data_auth::CRYPTOHOME_ERROR_NOT_SET);
            std::move(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,
                    base::OnceCallback<void(
                        const tpm_manager::GetVersionInfoReply& /*reply*/)>
                        success_callback,
                    base::OnceCallback<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");
            std::move(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,
                    base::OnceCallback<void(
                        const user_data_auth::GetLoginStatusReply& /*reply*/)>
                        success_callback,
                    base::OnceCallback<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);
            std::move(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,
                    base::OnceCallback<void(
                        const tpm_manager::GetTpmStatusReply& /*reply*/)>
                        success_callback,
                    base::OnceCallback<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.
                std::move(success_callback).Run(reply.value());
              } else {
                // If not, the method will return an error.
                std::move(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,
                base::OnceCallback<void(
                    const tpm_manager::GetDictionaryAttackInfoReply& /*reply*/)>
                    success_callback,
                base::OnceCallback<void(brillo::Error*)> error_callback,
                int timeout_ms) {
              if (reply.has_value()) {
                std::move(success_callback).Run(reply.value());
              } else {
                std::move(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,
                    base::OnceCallback<void(
                        const user_data_auth::
                            InstallAttributesGetStatusReply& /*reply*/)>
                        success_callback,
                    base::OnceCallback<void(brillo::Error*)> error_callback,
                    int timeout_ms) {
              if (reply.has_value()) {
                std::move(success_callback).Run(reply.value());
              } else {
                std::move(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,
                    base::OnceCallback<void(
                        const attestation::GetStatusReply& /*reply*/)>
                        success_callback,
                    base::OnceCallback<void(brillo::Error*)> error_callback,
                    int timeout_ms) {
              if (reply.has_value()) {
                std::move(success_callback).Run(reply.value());
              } else {
                std::move(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
