// 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 "biod/cros_fp_biometrics_manager.h"

#include <algorithm>
#include <utility>

#include <base/base64.h>
#include <base/bind.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_object_proxy.h>
#include <gtest/gtest.h>
#include <base/test/task_environment.h>

#include "biod/biod_crypto.h"
#include "biod/biod_crypto_test_data.h"
#include "biod/cros_fp_device_interface.h"
#include "biod/mock_biod_metrics.h"
#include "biod/mock_cros_fp_biometrics_manager.h"
#include "biod/mock_cros_fp_device.h"
#include "biod/mock_cros_fp_record_manager.h"

namespace biod {

using Mode = ec::FpMode::Mode;

namespace {
constexpr int kMaxPartialAttempts = 20;
constexpr int kMaxTemplateCount = 5;
constexpr char kRecordID[] = "record0";
constexpr char kData1[] = "some_super_interesting_data1";
constexpr char kLabel[] = "label0";
constexpr char kTemplateMetadataVersion0[] =
    "AAAdY8N2B+A/3Bz/Z7jZQId8OTgBksdFxjlWXzZ4lRg/GhE+MazZtq6M2tcMUk7e";
constexpr char kTemplateMetadataVersion1[] =
    "AQDPIyylfuu1jT+nf5x3WHdWnunhRyVh5tIu4jo+mM0rztdi50id7XMFPycVJHoR";
}  // namespace

using crypto_test_data::kFakePositiveMatchSecret1;
using crypto_test_data::kFakePositiveMatchSecret2;
using crypto_test_data::kFakeValidationValue1;
using crypto_test_data::kFakeValidationValue2;
using crypto_test_data::kUserID;

using testing::_;
using testing::ByMove;
using testing::Return;
using testing::ReturnRef;
using testing::SaveArg;

// Using a peer class to control access to the class under test is better than
// making the text fixture a friend class.
class CrosFpBiometricsManagerPeer {
 public:
  CrosFpBiometricsManagerPeer(
      std::unique_ptr<CrosFpBiometricsManager> cros_fp_biometrics_manager)
      : cros_fp_biometrics_manager_(std::move(cros_fp_biometrics_manager)) {}

  // Methods to execute CrosFpBiometricsManager private methods.

  bool ValidationValueEquals(const std::string& id,
                             const std::vector<uint8_t>& reference_value) {
    return cros_fp_biometrics_manager_->GetRecordMetadata(id)->validation_val ==
           reference_value;
  }

  bool ComputeValidationValue(const brillo::SecureVector& secret,
                              const std::string& user_id,
                              std::vector<uint8_t>* out) {
    return BiodCrypto::ComputeValidationValue(secret, user_id, out);
  }

  bool CheckPositiveMatchSecret(const std::string& record_id, int match_idx) {
    return cros_fp_biometrics_manager_->CheckPositiveMatchSecret(record_id,
                                                                 match_idx);
  }

  void AddLoadedRecord(const std::string& record_id) {
    cros_fp_biometrics_manager_->loaded_records_.emplace_back(record_id);
  }

 private:
  std::unique_ptr<CrosFpBiometricsManager> cros_fp_biometrics_manager_;
};

class CrosFpBiometricsManagerTest : public ::testing::Test {
 public:
  CrosFpBiometricsManagerTest() {
    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    const auto mock_bus = base::MakeRefCounted<dbus::MockBus>(options);

    // Set EXPECT_CALL, otherwise gmock forces an failure due to "uninteresting
    // call" because we use StrictMock.
    // https://github.com/google/googletest/blob/fb49e6c164490a227bbb7cf5223b846c836a0305/googlemock/docs/cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy
    const auto power_manager_proxy =
        base::MakeRefCounted<dbus::MockObjectProxy>(
            mock_bus.get(), power_manager::kPowerManagerServiceName,
            dbus::ObjectPath(power_manager::kPowerManagerServicePath));
    EXPECT_CALL(*mock_bus,
                GetObjectProxy(
                    power_manager::kPowerManagerServiceName,
                    dbus::ObjectPath(power_manager::kPowerManagerServicePath)))
        .WillOnce(testing::Return(power_manager_proxy.get()));

    auto mock_cros_dev = std::make_unique<MockCrosFpDevice>();
    // Keep a pointer to the fake device to manipulate it later.
    mock_cros_dev_ = mock_cros_dev.get();

    auto mock_record_manager = std::make_unique<MockCrosFpRecordManager>();
    // Keep a pointer to record manager, to manipulate it later.
    mock_record_manager_ = mock_record_manager.get();

    // Always support positive match secret
    EXPECT_CALL(*mock_cros_dev_, SupportsPositiveMatchSecret())
        .WillRepeatedly(Return(true));

    // Save OnMkbpEvent callback to use later in tests
    ON_CALL(*mock_cros_dev_, SetMkbpEventCallback)
        .WillByDefault(SaveArg<0>(&on_mkbp_event_));

    auto cros_fp_biometrics_manager = std::make_unique<CrosFpBiometricsManager>(
        PowerButtonFilter::Create(mock_bus), std::move(mock_cros_dev),
        std::make_unique<metrics::MockBiodMetrics>(),
        std::move(mock_record_manager));
    cros_fp_biometrics_manager_ = cros_fp_biometrics_manager.get();

    // Register OnAuthScanDone and OnSessionFailed callbacks which are actually
    // mocks. That way we can conveniently handle these calls without
    // using lambda.
    cros_fp_biometrics_manager_->SetAuthScanDoneHandler(
        base::BindRepeating(&CrosFpBiometricsManagerTest::AuthScanDoneHandler,
                            base::Unretained(this)));
    cros_fp_biometrics_manager_->SetSessionFailedHandler(
        base::BindRepeating(&CrosFpBiometricsManagerTest::SessionFailedHandler,
                            base::Unretained(this)));

    cros_fp_biometrics_manager_peer_.emplace(
        std::move(cros_fp_biometrics_manager));
  }

  MOCK_METHOD(void,
              AuthScanDoneHandler,
              (biod::FingerprintMessage result,
               BiometricsManager::AttemptMatches matches));
  MOCK_METHOD(void, SessionFailedHandler, ());

 protected:
  std::optional<CrosFpBiometricsManagerPeer> cros_fp_biometrics_manager_peer_;
  MockCrosFpRecordManager* mock_record_manager_;
  MockCrosFpDevice* mock_cros_dev_;
  CrosFpBiometricsManager* cros_fp_biometrics_manager_;
  CrosFpDevice::MkbpCallback on_mkbp_event_;
};

TEST_F(CrosFpBiometricsManagerTest, TestComputeValidationValue) {
  const std::vector<std::pair<brillo::SecureVector, std::vector<uint8_t>>>
      kSecretValidationValuePairs = {
          std::make_pair(kFakePositiveMatchSecret1, kFakeValidationValue1),
          std::make_pair(kFakePositiveMatchSecret2, kFakeValidationValue2),
      };
  for (const auto& pair : kSecretValidationValuePairs) {
    std::vector<uint8_t> validation_value;
    EXPECT_TRUE(cros_fp_biometrics_manager_peer_->ComputeValidationValue(
        pair.first, kUserID, &validation_value));
    EXPECT_EQ(validation_value, pair.second);
  }
}

TEST_F(CrosFpBiometricsManagerTest, TestValidationValueCalculation) {
  const BiodStorageInterface::RecordMetadata kMetadata1{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};

  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata)
      .WillRepeatedly(Return(kMetadata1));
  EXPECT_CALL(*mock_cros_dev_, GetPositiveMatchSecret)
      .WillOnce(Return(kFakePositiveMatchSecret1));
  EXPECT_TRUE(
      cros_fp_biometrics_manager_peer_->CheckPositiveMatchSecret(kRecordID, 0));
}

TEST_F(CrosFpBiometricsManagerTest, TestPositiveMatchSecretIsCorrect) {
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata(kRecordID))
      .WillRepeatedly(Return(kMetadata));

  EXPECT_CALL(*mock_cros_dev_, GetPositiveMatchSecret)
      .WillOnce(Return(kFakePositiveMatchSecret1));
  EXPECT_TRUE(
      cros_fp_biometrics_manager_peer_->CheckPositiveMatchSecret(kRecordID, 0));
}

TEST_F(CrosFpBiometricsManagerTest, TestPositiveMatchSecretIsNotCorrect) {
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue2};
  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata(kRecordID))
      .WillRepeatedly(Return(kMetadata));

  EXPECT_CALL(*mock_cros_dev_, GetPositiveMatchSecret)
      .WillOnce(Return(kFakePositiveMatchSecret1));
  EXPECT_FALSE(
      cros_fp_biometrics_manager_peer_->CheckPositiveMatchSecret(kRecordID, 0));
}

TEST_F(CrosFpBiometricsManagerTest, TestCheckPositiveMatchSecretNoSecret) {
  EXPECT_CALL(*mock_cros_dev_, GetPositiveMatchSecret)
      .WillOnce(Return(base::nullopt));
  EXPECT_FALSE(
      cros_fp_biometrics_manager_peer_->CheckPositiveMatchSecret(kRecordID, 0));
}

TEST_F(CrosFpBiometricsManagerTest, TestInvalidRecordsAreDeletedWhileReading) {
  EXPECT_CALL(*mock_record_manager_, UserHasInvalidRecords(kUserID))
      .WillOnce(Return(true));
  EXPECT_CALL(*mock_record_manager_, DeleteInvalidRecords);

  EXPECT_FALSE(cros_fp_biometrics_manager_->ReadRecordsForSingleUser(kUserID));
}

TEST_F(CrosFpBiometricsManagerTest, TestCheckPositiveMatchSecret) {
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata(kRecordID))
      .WillRepeatedly(Return(kMetadata));
  EXPECT_CALL(*mock_cros_dev_, GetPositiveMatchSecret)
      .WillOnce(Return(kFakePositiveMatchSecret1));
  EXPECT_TRUE(
      cros_fp_biometrics_manager_peer_->CheckPositiveMatchSecret(kRecordID, 0));
}

TEST_F(CrosFpBiometricsManagerTest, TestLoadingTemplate) {
  std::string template_decoded;
  base::Base64Decode(kTemplateMetadataVersion0, &template_decoded);
  VendorTemplate tmpl(template_decoded.begin(), template_decoded.end());
  EXPECT_EQ(tmpl.size(), sizeof(struct ec_fp_template_encryption_metadata));

  // Expect that biod will send correct record data to FPMCU.
  EXPECT_CALL(*mock_cros_dev_, UploadTemplate(tmpl)).WillOnce(Return(true));

  std::vector<Record> user_records({{{kRecordFormatVersion, kRecordID, kUserID,
                                      kLabel, kFakeValidationValue1},
                                     kTemplateMetadataVersion0}});

  EXPECT_CALL(*mock_record_manager_, GetRecordsForUser)
      .WillOnce(Return(user_records));
  EXPECT_CALL(*mock_cros_dev_, MaxTemplateCount)
      .WillRepeatedly(Return(kMaxTemplateCount));
  EXPECT_TRUE(cros_fp_biometrics_manager_->ReadRecordsForSingleUser(kUserID));
}

TEST_F(CrosFpBiometricsManagerTest, TestLoadingTemplateUploadError) {
  std::vector<Record> user_records({{{kRecordFormatVersion, kRecordID, kUserID,
                                      kLabel, kFakeValidationValue1},
                                     kTemplateMetadataVersion0}});

  EXPECT_CALL(*mock_record_manager_, GetRecordsForUser)
      .WillOnce(Return(user_records));
  EXPECT_CALL(*mock_cros_dev_, MaxTemplateCount)
      .WillRepeatedly(Return(kMaxTemplateCount));
  EXPECT_CALL(*mock_cros_dev_, UploadTemplate).WillOnce(Return(false));
  // Still expect true, because there are no invalid records
  EXPECT_TRUE(cros_fp_biometrics_manager_->ReadRecordsForSingleUser(kUserID));
}

TEST_F(CrosFpBiometricsManagerTest, TestLoadingTemplateInvalidVersion) {
  std::vector<Record> user_records({{{kRecordFormatVersion, kRecordID, kUserID,
                                      kLabel, kFakeValidationValue1},
                                     kTemplateMetadataVersion1}});

  EXPECT_CALL(*mock_record_manager_, GetRecordsForUser)
      .WillOnce(Return(user_records));
  EXPECT_CALL(*mock_record_manager_, DeleteRecord(kRecordID))
      .WillOnce(Return(true));
  EXPECT_CALL(*mock_cros_dev_, MaxTemplateCount)
      .WillRepeatedly(Return(kMaxTemplateCount));
  EXPECT_CALL(*mock_cros_dev_, UploadTemplate).Times(0);
  // Still expect true, because there are no invalid records
  EXPECT_TRUE(cros_fp_biometrics_manager_->ReadRecordsForSingleUser(kUserID));
}

TEST_F(CrosFpBiometricsManagerTest, TestLoadingTemplateNoSpaceAvailable) {
  std::vector<Record> user_records({{{kRecordFormatVersion, kRecordID, kUserID,
                                      kLabel, kFakeValidationValue1},
                                     kData1}});

  EXPECT_CALL(*mock_record_manager_, GetRecordsForUser)
      .WillOnce(Return(user_records));
  EXPECT_CALL(*mock_cros_dev_, MaxTemplateCount).WillRepeatedly(Return(0));
  EXPECT_CALL(*mock_cros_dev_, UploadTemplate).Times(0);
  // Still expect true, because there are no invalid records
  EXPECT_TRUE(cros_fp_biometrics_manager_->ReadRecordsForSingleUser(kUserID));
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionStartStopSuccess) {
  BiometricsManager::AuthSession auth_session;

  // Expect that biod will ask FPMCU to set the match mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode(ec::FpMode(Mode::kMatch)))
      .WillOnce(Return(true));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // When auth session ends, FP mode will be set to kNone.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode(ec::FpMode(Mode::kNone)))
      .WillOnce(Return(true));

  // Stop auth session
  auth_session.End();
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionMatchModeFailed) {
  BiometricsManager::AuthSession auth_session;

  // Expect that biod will ask FPMCU to set the match mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode(ec::FpMode(Mode::kMatch)))
      .WillOnce(Return(false));

  // Auth session should fail to start when FPMCU refuses to set match mode.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_FALSE(auth_session);
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionRequestsFingerUp) {
  BiometricsManager::AuthSession auth_session;

  // Expect that biod will ask FPMCU to set the match mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode(ec::FpMode(Mode::kMatch)))
      .WillOnce(Return(true));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Biod will set FP mode to FingerUp, when calling on_mkbp_event_.Run.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode(ec::FpMode(Mode::kFingerUp)))
      .WillOnce(Return(true));

  // When auth session ends, FP mode will be set to kNone.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode(ec::FpMode(Mode::kNone)))
      .WillOnce(Return(true));

  // Send response from Cros FP. Finger up should be requested regardless of
  // response from FPMCU
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH);
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionRequestsFingerUpFailed) {
  BiometricsManager::AuthSession auth_session;

  // Expect that biod will ask FPMCU to set the match mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode(ec::FpMode(Mode::kMatch)))
      .WillOnce(Return(true));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Biod will set FP mode to FingerUp, when calling on_mkbp_event_.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode(ec::FpMode(Mode::kFingerUp)))
      .WillOnce(Return(false));

  // Expect that OnSessionFailed callback is called.
  EXPECT_CALL(*this, SessionFailedHandler).Times(1);

  // When auth session ends, FP mode will be set to kNone.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode(ec::FpMode(Mode::kNone)))
      .WillOnce(Return(true));

  // Send response from Cros FP. Finger up should be requested regardless of
  // response from FPMCU
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH);
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionSuccessNoUpdate) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  const BiometricsManager::AttemptMatches kExpectedMatches(
      {{std::string(kUserID), std::vector<std::string>({kRecordID})}});
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Give record details if asked.
  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata)
      .WillRepeatedly(Return(kMetadata));

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  // Pretend that we have some records loaded.
  cros_fp_biometrics_manager_peer_->AddLoadedRecord(kMetadata.record_id);

  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  EXPECT_CALL(*mock_cros_dev_, GetPositiveMatchSecret)
      .WillOnce(Return(kFakePositiveMatchSecret1));

  // Send response from Cros FP.
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_YES);

  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kScanResult);
  EXPECT_EQ(msg.scan_result(), ScanResult::SCAN_RESULT_SUCCESS);
  EXPECT_EQ(received_matches, kExpectedMatches);
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionFailedInvalidTemplate) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  // No records are loaded, so don't expect asking for record details.
  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata).Times(0);

  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Send response from Cros FP.
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_YES);

  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kError);
  EXPECT_EQ(msg.error(), FingerprintError::ERROR_UNABLE_TO_PROCESS);
  EXPECT_TRUE(received_matches.empty());
}

TEST_F(CrosFpBiometricsManagerTest,
       TestAuthSessionFailedInvalidPositiveMatchSecret) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Give record details if asked.
  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata)
      .WillRepeatedly(Return(kMetadata));

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  // Pretend that we have some records loaded.
  cros_fp_biometrics_manager_peer_->AddLoadedRecord(kMetadata.record_id);

  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Return wrong Positive Match Secret.
  EXPECT_CALL(*mock_cros_dev_, GetPositiveMatchSecret)
      .WillOnce(Return(kFakePositiveMatchSecret2));

  // Send response from Cros FP.
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_YES);

  // Expected values when Positive Match Secret is not correct.
  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kError);
  EXPECT_EQ(msg.error(), FingerprintError::ERROR_UNABLE_TO_PROCESS);
  EXPECT_TRUE(received_matches.empty());
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionMatchNo) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  // If result is different than MATCH_YES, then we expect to receive
  // empty matches.
  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Send response from Cros FP.
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_NO);

  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kScanResult);
  EXPECT_EQ(msg.scan_result(), ScanResult::SCAN_RESULT_NO_MATCH);
  EXPECT_TRUE(received_matches.empty());
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionMatchNoTemplates) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Send response from Cros FP.
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_NO_TEMPLATES);

  // Expected values when FPMCU reports no templates.
  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kError);
  EXPECT_EQ(msg.error(), FingerprintError::ERROR_NO_TEMPLATES);
  EXPECT_TRUE(received_matches.empty());
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionMatchNoInternal) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Send response from Cros FP.
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_NO_INTERNAL);

  // Expected values when FPMCU reports internal error.
  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kError);
  EXPECT_EQ(msg.error(), FingerprintError::ERROR_UNABLE_TO_PROCESS);
  EXPECT_TRUE(received_matches.empty());
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionMatchNoLowQuality) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Send response from Cros FP.
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_NO_LOW_QUALITY);

  // Expected values when FPMCU reports scan is low quality.
  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kScanResult);
  EXPECT_EQ(msg.scan_result(), ScanResult::SCAN_RESULT_INSUFFICIENT);
  EXPECT_TRUE(received_matches.empty());
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionMatchNoLowCoverage) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Send response from Cros FP.
  // DoMatchEvent will automatically retry the LOW_COVERAGE event (without
  // ending the AuthSession) up to kMaxPartialAttempts times.
  // When kMaxPartialAttempts is reached, AuthScanDoneHandler will be
  // called with SCAN_RESULT_PARTIAL.
  for (int i = 0; i < kMaxPartialAttempts + 1; i++) {
    on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_NO_LOW_COVERAGE);
  }

  // Expected values when FPMCU reports scan has low coverage.
  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kScanResult);
  EXPECT_EQ(msg.scan_result(), ScanResult::SCAN_RESULT_PARTIAL);
  EXPECT_TRUE(received_matches.empty());
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionSuccessAfterLowCoverage) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  const BiometricsManager::AttemptMatches kExpectedMatches(
      {{std::string(kUserID), std::vector<std::string>({kRecordID})}});
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Give record details if asked.
  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata)
      .WillRepeatedly(Return(kMetadata));

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  // Pretend that we have some records loaded.
  cros_fp_biometrics_manager_peer_->AddLoadedRecord(kMetadata.record_id);

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Send LOW_COVERAGE for kMaxPartialAttempts/2 times then send MATCH_YES.
  // DoMatchEvent will automatically retry the LOW_COVERAGE event (without
  // ending the AuthSession) up to kMaxPartialAttempts times.
  for (int i = 0; i < kMaxPartialAttempts / 2; i++) {
    on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_NO_LOW_COVERAGE);
  }

  EXPECT_CALL(*mock_cros_dev_, GetPositiveMatchSecret)
      .WillOnce(Return(kFakePositiveMatchSecret1));

  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_YES);

  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kScanResult);
  EXPECT_EQ(msg.scan_result(), ScanResult::SCAN_RESULT_SUCCESS);
  EXPECT_EQ(received_matches, kExpectedMatches);
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionMatchUnknownCode) {
  BiometricsManager::AuthSession auth_session;

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  // When code from FPMCU is unknown a failure is expected..
  EXPECT_CALL(*this, AuthScanDoneHandler).Times(0);
  EXPECT_CALL(*this, SessionFailedHandler).Times(1);

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  // Send response from Cros FP.
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | 15);
}

TEST_F(CrosFpBiometricsManagerTest, TestAuthSessionSuccessUpdated) {
  BiometricsManager::AuthSession auth_session;
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  const BiometricsManager::AttemptMatches kExpectedMatches(
      {{std::string(kUserID), std::vector<std::string>({kRecordID})}});
  BiometricsManager::AttemptMatches received_matches;
  biod::FingerprintMessage msg;

  // Give record details if asked.
  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata)
      .WillRepeatedly(Return(kMetadata));

  // Always allow setting FP mode.
  EXPECT_CALL(*mock_cros_dev_, SetFpMode).WillRepeatedly(Return(true));

  // Pretend that we have some records loaded.
  cros_fp_biometrics_manager_peer_->AddLoadedRecord(kMetadata.record_id);

  EXPECT_CALL(*this, AuthScanDoneHandler)
      .WillOnce(DoAll(SaveArg<0>(&msg), SaveArg<1>(&received_matches)));

  // Start auth session.
  auth_session = cros_fp_biometrics_manager_->StartAuthSession();
  EXPECT_TRUE(auth_session);

  EXPECT_CALL(*mock_cros_dev_, GetPositiveMatchSecret)
      .WillOnce(Return(kFakePositiveMatchSecret1));

  // Return information that template 0 was updated
  EXPECT_CALL(*mock_cros_dev_, GetDirtyMap)
      .WillOnce(Return(std::bitset<32>(1)));

  EXPECT_CALL(*mock_cros_dev_, GetTemplate)
      .WillOnce(Return(ByMove(std::make_unique<VendorTemplate>())));

  EXPECT_CALL(*mock_record_manager_, UpdateRecord(kMetadata, _))
      .WillOnce(Return(true));

  // Send response from Cros FP.
  on_mkbp_event_.Run(EC_MKBP_FP_MATCH | EC_MKBP_FP_ERR_MATCH_YES_UPDATED);

  EXPECT_EQ(msg.msg_case(), biod::FingerprintMessage::MsgCase::kScanResult);
  EXPECT_EQ(msg.scan_result(), ScanResult::SCAN_RESULT_SUCCESS);
  EXPECT_EQ(received_matches, kExpectedMatches);
}

class CrosFpBiometricsManagerMockTest : public ::testing::Test {
 protected:
  CrosFpBiometricsManagerMockTest() {
    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    const auto mock_bus = base::MakeRefCounted<dbus::MockBus>(options);

    // Set EXPECT_CALL, otherwise gmock forces an failure due to "uninteresting
    // call" because we use StrictMock.
    // https://github.com/google/googletest/blob/fb49e6c164490a227bbb7cf5223b846c836a0305/googlemock/docs/cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy
    power_manager_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>(
        mock_bus.get(), power_manager::kPowerManagerServiceName,
        dbus::ObjectPath(power_manager::kPowerManagerServicePath));
    EXPECT_CALL(*mock_bus,
                GetObjectProxy(
                    power_manager::kPowerManagerServiceName,
                    dbus::ObjectPath(power_manager::kPowerManagerServicePath)))
        .WillOnce(testing::Return(power_manager_proxy_.get()));

    // Keep a pointer to the mocks so they can be used in the tests. The
    // pointers must come after the MockCrosFpBiometricsManager pointer in the
    // class so that MockCrosFpBiometricsManager outlives the bare pointers,
    // since MockCrosFpBiometricsManager maintains ownership of the underlying
    // objects.
    auto mock_cros_fp_dev = std::make_unique<MockCrosFpDevice>();
    mock_cros_dev_ = mock_cros_fp_dev.get();
    auto mock_biod_metrics = std::make_unique<metrics::MockBiodMetrics>();
    mock_metrics_ = mock_biod_metrics.get();
    auto mock_record_manager = std::make_unique<MockCrosFpRecordManager>();
    mock_record_manager_ = mock_record_manager.get();

    EXPECT_CALL(*mock_cros_dev_, SupportsPositiveMatchSecret())
        .WillRepeatedly(Return(true));

    mock_ = std::make_unique<MockCrosFpBiometricsManager>(
        PowerButtonFilter::Create(mock_bus), std::move(mock_cros_fp_dev),
        std::move(mock_biod_metrics), std::move(mock_record_manager));
    EXPECT_TRUE(mock_);
  }

  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  scoped_refptr<dbus::MockObjectProxy> power_manager_proxy_;
  std::unique_ptr<MockCrosFpBiometricsManager> mock_;
  MockCrosFpDevice* mock_cros_dev_;
  metrics::MockBiodMetrics* mock_metrics_;
  MockCrosFpRecordManager* mock_record_manager_;
};

// TODO(b/187951992): The following tests for the automatic maintenance timer
// need to be re-enabled when the maintenace-auth interference is fixed.
// The tests were disabled due to b/184783529.
TEST_F(CrosFpBiometricsManagerMockTest,
       DISABLED_TestMaintenanceTimer_TooShort) {
  EXPECT_CALL(*mock_, OnMaintenanceTimerFired).Times(0);
  task_environment_.FastForwardBy(base::TimeDelta::FromHours(12));
}

TEST_F(CrosFpBiometricsManagerMockTest, DISABLED_TestMaintenanceTimer_Once) {
  EXPECT_CALL(*mock_, OnMaintenanceTimerFired).Times(1);
  task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
}

TEST_F(CrosFpBiometricsManagerMockTest,
       DISABLED_TestMaintenanceTimer_Multiple) {
  EXPECT_CALL(*mock_, OnMaintenanceTimerFired).Times(2);
  task_environment_.FastForwardBy(base::TimeDelta::FromDays(2));
}

// TODO(b/187951992): The following test must be removed when the
// maintenace-auth interference is fixed.
// This test was added when the maintenance timer was disabled due to
// b/184783529.
TEST_F(CrosFpBiometricsManagerMockTest, TestMaintenanceTimer_Disabled) {
  EXPECT_CALL(*mock_, OnMaintenanceTimerFired).Times(0);
  task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
}

TEST_F(CrosFpBiometricsManagerMockTest, TestOnMaintenanceTimerFired) {
  constexpr int kNumDeadPixels = 1;

  EXPECT_NE(mock_cros_dev_, nullptr);
  EXPECT_NE(mock_metrics_, nullptr);

  EXPECT_CALL(*mock_metrics_, SendDeadPixelCount(kNumDeadPixels)).Times(1);

  EXPECT_CALL(*mock_cros_dev_, DeadPixelCount)
      .WillOnce(testing::Return(kNumDeadPixels));

  EXPECT_CALL(*mock_cros_dev_,
              SetFpMode(ec::FpMode(ec::FpMode::Mode::kSensorMaintenance)))
      .Times(1);

  mock_->OnMaintenanceTimerFiredDelegate();
}

TEST_F(CrosFpBiometricsManagerMockTest, TestGetDirtyList_Empty) {
  EXPECT_CALL(*mock_cros_dev_, GetDirtyMap).WillOnce(Return(std::bitset<32>()));
  auto dirty_list = mock_->GetDirtyList();
  EXPECT_EQ(dirty_list, std::vector<int>());
}

TEST_F(CrosFpBiometricsManagerMockTest, TestGetDirtyList) {
  EXPECT_CALL(*mock_cros_dev_, GetDirtyMap)
      .WillOnce(Return(std::bitset<32>("1001")));
  auto dirty_list = mock_->GetDirtyList();
  EXPECT_EQ(dirty_list, (std::vector<int>{0, 3}));
}

TEST_F(CrosFpBiometricsManagerMockTest, TestUpdateTemplatesOnDisk) {
  const BiodStorageInterface::RecordMetadata kMetadata{
      kRecordFormatVersion, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  const std::vector<int> dirty_list = {0};
  const std::unordered_set<uint32_t> suspicious_templates;

  EXPECT_CALL(*mock_cros_dev_, GetTemplate)
      .WillOnce(Return(ByMove(std::make_unique<VendorTemplate>())));

  EXPECT_CALL(*mock_, GetLoadedRecordId(0)).WillRepeatedly(Return(kRecordID));
  EXPECT_CALL(*mock_record_manager_, GetRecordMetadata(kRecordID))
      .WillRepeatedly(Return(kMetadata));
  EXPECT_CALL(*mock_record_manager_, UpdateRecord(kMetadata, _))
      .WillOnce(Return(true));

  EXPECT_TRUE(mock_->UpdateTemplatesOnDisk(dirty_list, suspicious_templates));
}

TEST_F(CrosFpBiometricsManagerMockTest,
       TestUpdateTemplatesOnDisk_RecordNotAvailable) {
  const std::vector<int> dirty_list = {0};
  const std::unordered_set<uint32_t> suspicious_templates;

  EXPECT_CALL(*mock_, GetLoadedRecordId(0)).WillOnce(Return(base::nullopt));
  EXPECT_CALL(*mock_cros_dev_, GetTemplate).Times(0);
  EXPECT_CALL(*mock_record_manager_, UpdateRecord).Times(0);

  EXPECT_TRUE(mock_->UpdateTemplatesOnDisk(dirty_list, suspicious_templates));
}

TEST_F(CrosFpBiometricsManagerMockTest,
       TestUpdateTemplatesOnDisk_NoDirtyTemplates) {
  const std::vector<int> dirty_list;
  const std::unordered_set<uint32_t> suspicious_templates;

  EXPECT_CALL(*mock_record_manager_, UpdateRecord).Times(0);

  EXPECT_TRUE(mock_->UpdateTemplatesOnDisk(dirty_list, suspicious_templates));
}

TEST_F(CrosFpBiometricsManagerMockTest,
       TestUpdateTemplatesOnDisk_SkipSuspiciousTemplates) {
  const std::vector<int> dirty_list = {0};
  const std::unordered_set<uint32_t> suspicious_templates = {0};

  EXPECT_CALL(*mock_, GetLoadedRecordId(0)).WillRepeatedly(Return(kRecordID));
  EXPECT_CALL(*mock_record_manager_, UpdateRecord).Times(0);

  EXPECT_TRUE(mock_->UpdateTemplatesOnDisk(dirty_list, suspicious_templates));
}

TEST_F(CrosFpBiometricsManagerMockTest,
       TestUpdateTemplatesOnDisk_ErrorFetchingTemplate) {
  const std::vector<int> dirty_list = {0};
  const std::unordered_set<uint32_t> suspicious_templates;

  EXPECT_CALL(*mock_, GetLoadedRecordId(0)).WillRepeatedly(Return(kRecordID));
  EXPECT_CALL(*mock_cros_dev_, GetTemplate).Times(1);
  EXPECT_CALL(*mock_record_manager_, UpdateRecord).Times(0);

  EXPECT_TRUE(mock_->UpdateTemplatesOnDisk(dirty_list, suspicious_templates));
}

TEST_F(CrosFpBiometricsManagerMockTest, TestCallDeleteRecord) {
  EXPECT_CALL(*mock_cros_dev_, MaxTemplateCount).WillOnce(Return(5));

  EXPECT_CALL(*mock_record_manager_, DeleteRecord);

  struct ec_fp_template_encryption_metadata Data = {0};
  Data.struct_version = 0x3;  // Correct version is zero.
  const BiodStorageInterface::RecordMetadata mock_test_recordmetadata{
      1, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  const BiodStorageInterface::Record mock_test_record{
      mock_test_recordmetadata,
      base::Base64Encode(base::as_bytes(base::make_span(&Data, sizeof(Data))))};
  mock_->LoadRecord(mock_test_record);
}

TEST_F(CrosFpBiometricsManagerMockTest, TestSkipDeleteRecord) {
  EXPECT_CALL(*mock_cros_dev_, MaxTemplateCount).WillOnce(Return(5));

  EXPECT_CALL(*mock_record_manager_, DeleteRecord).Times(0);

  struct ec_fp_template_encryption_metadata Data = {0};
  // Template version is zero because it comes from mock.
  const BiodStorageInterface::RecordMetadata mock_test_recordmetadata{
      1, kRecordID, kUserID, kLabel, kFakeValidationValue1};
  const BiodStorageInterface::Record mock_test_record{
      mock_test_recordmetadata,
      base::Base64Encode(base::as_bytes(base::make_span(&Data, sizeof(Data))))};
  mock_->LoadRecord(mock_test_record);
}

}  // namespace biod
