// Copyright 2017 The Chromium 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 "chromeos/dbus/biod/fake_biod_client.h"

#include <vector>

#include "base/bind.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chromeos/dbus/biod/test_utils.h"
#include "dbus/object_path.h"
#include "testing/gtest/include/gtest/gtest.h"

using biod::SCAN_RESULT_SUCCESS;

namespace chromeos {

namespace {

const char kTestUserId[] = "testuser@gmail.com";
const char kTestLabel[] = "testLabel";
// Template of a scan string to be used in GenerateTestFingerprint. The # and $
// are two wildcards that will be replaced by numbers to ensure unique scans.
const char kTestScan[] = "finger#scan$";

}  // namepsace

class FakeBiodClientTest : public testing::Test {
 public:
  FakeBiodClientTest()
      : task_runner_(new base::TestSimpleTaskRunner),
        task_runner_handle_(task_runner_) {}
  ~FakeBiodClientTest() override = default;

  // Returns the stored records for |user_id|. Verified to work in
  // TestGetRecordsForUser.
  std::vector<dbus::ObjectPath> GetRecordsForUser(const std::string& user_id) {
    std::vector<dbus::ObjectPath> enrollment_paths;
    fake_biod_client_.GetRecordsForUser(
        user_id,
        base::Bind(&test_utils::CopyObjectPathArray, &enrollment_paths));
    task_runner_->RunUntilIdle();
    return enrollment_paths;
  }

  // Helper function which enrolls a fingerprint. Each element in
  // |fingerprint_data| corresponds to a finger tap.
  void EnrollFingerprint(const std::string& id,
                         const std::string& label,
                         const std::vector<std::string>& fingerprint_data) {
    ASSERT_FALSE(fingerprint_data.empty());

    dbus::ObjectPath returned_path;
    fake_biod_client_.StartEnrollSession(
        id, label, base::Bind(&test_utils::CopyObjectPath, &returned_path));
    task_runner_->RunUntilIdle();
    EXPECT_NE(dbus::ObjectPath(), returned_path);

    // Send |fingerprint_data| size - 1 incomplete scans, then finish the
    // enrollment by sending a complete scan signal.
    for (size_t i = 0; i < fingerprint_data.size(); ++i) {
      fake_biod_client_.SendEnrollScanDone(
          fingerprint_data[i], SCAN_RESULT_SUCCESS,
          i == fingerprint_data.size() - 1 /* is_complete */,
          -1 /* percent_complete */);
    }
  }

  // Helper function which enrolls |n| fingerprints with the same |id|, |label|
  // and |fingerprint_data|.
  void EnrollNTestFingerprints(const std::string& id,
                               const std::string& label,
                               const std::vector<std::string>& fingerprint_data,
                               int n) {
    for (int i = 0; i < n; ++i)
      EnrollFingerprint(id, label, fingerprint_data);
  }

  // Creates a new unique fingerprint consisting of unique scans.
  std::vector<std::string> GenerateTestFingerprint(int scans) {
    EXPECT_GE(scans, 0);
    num_test_fingerprints_++;

    std::vector<std::string> fingerprint;
    for (int i = 0; i < scans; ++i) {
      std::string scan = kTestScan;
      base::ReplaceSubstringsAfterOffset(
          &scan, 0, "#", std::to_string(num_test_fingerprints_));
      base::ReplaceSubstringsAfterOffset(&scan, 0, "$", std::to_string(i));
      fingerprint.push_back(scan);
    }
    return fingerprint;
  }

 protected:
  FakeBiodClient fake_biod_client_;
  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
  base::ThreadTaskRunnerHandle task_runner_handle_;

  // This number is incremented each time GenerateTestFingerprint is called to
  // ensure each fingerprint is unique.
  int num_test_fingerprints_ = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(FakeBiodClientTest);
};

TEST_F(FakeBiodClientTest, TestEnrollSessionWorkflow) {
  test_utils::TestBiodObserver observer;
  fake_biod_client_.AddObserver(&observer);

  const std::vector<std::string>& kTestFingerprint = GenerateTestFingerprint(2);
  // Verify that successful enrollments get stored as expected. A fingerprint
  // that was created with 2 scans should have 1 incomplete scan and 1 complete
  // scan.
  EnrollFingerprint(kTestUserId, kTestLabel, kTestFingerprint);
  EXPECT_EQ(1u, GetRecordsForUser(kTestUserId).size());
  EXPECT_EQ(1, observer.num_incomplete_enroll_scans_received());
  EXPECT_EQ(1, observer.num_complete_enroll_scans_received());

  // Verify that the enroll session worflow can be used repeatedly by enrolling
  // 3 more fingerprints (each with 1 incomplete and 1 complete scan).
  observer.ResetAllCounts();
  EnrollNTestFingerprints(kTestUserId, kTestLabel, kTestFingerprint, 3);
  EXPECT_EQ(4u, GetRecordsForUser(kTestUserId).size());
  EXPECT_EQ(3, observer.num_incomplete_enroll_scans_received());
  EXPECT_EQ(3, observer.num_complete_enroll_scans_received());
}

// Test authentication when one user has one or more fingerprints registered.
// This should be the normal scenario.
TEST_F(FakeBiodClientTest, TestAuthSessionWorkflowSingleUser) {
  test_utils::TestBiodObserver observer;
  fake_biod_client_.AddObserver(&observer);
  EXPECT_EQ(0u, GetRecordsForUser(kTestUserId).size());

  const std::vector<std::string>& kTestFingerprint1 =
      GenerateTestFingerprint(2);
  const std::vector<std::string>& kTestFingerprint2 =
      GenerateTestFingerprint(2);
  const std::vector<std::string>& kTestFingerprint3 =
      GenerateTestFingerprint(2);
  const std::vector<std::string>& kTestFingerprint4 =
      GenerateTestFingerprint(2);

  // Add two fingerprints |kTestFingerprint1| and |kTestFingerprint2| and start
  // an auth session.
  EnrollFingerprint(kTestUserId, kTestLabel, kTestFingerprint1);
  EnrollFingerprint(kTestUserId, kTestLabel, kTestFingerprint2);
  dbus::ObjectPath returned_path;
  fake_biod_client_.StartAuthSession(
      base::Bind(&test_utils::CopyObjectPath, &returned_path));
  task_runner_->RunUntilIdle();
  EXPECT_NE(returned_path, dbus::ObjectPath());

  // Verify that by sending two attempt signals of fingerprints that have been
  // enrolled, the observer should receive two matches and zero non-matches.
  fake_biod_client_.SendAuthScanDone(kTestFingerprint1[0], SCAN_RESULT_SUCCESS);
  fake_biod_client_.SendAuthScanDone(kTestFingerprint2[0], SCAN_RESULT_SUCCESS);
  EXPECT_EQ(2, observer.num_matched_auth_scans_received());
  EXPECT_EQ(0, observer.num_unmatched_auth_scans_received());

  // Verify that by sending two attempt signals of fingerprints that have not
  // been enrolled, the observer should receive two non-matches and zero
  // matches.
  observer.ResetAllCounts();
  fake_biod_client_.SendAuthScanDone(kTestFingerprint3[0], SCAN_RESULT_SUCCESS);
  fake_biod_client_.SendAuthScanDone(kTestFingerprint4[0], SCAN_RESULT_SUCCESS);
  EXPECT_EQ(0, observer.num_matched_auth_scans_received());
  EXPECT_EQ(2, observer.num_unmatched_auth_scans_received());
}

// Test authentication when multiple users have fingerprints registered. Cover
// cases such as when both users use the same labels, a user had registered the
// same fingerprint multiple times, or two users use the same fingerprint.
TEST_F(FakeBiodClientTest, TestAuthenticateWorkflowMultipleUsers) {
  test_utils::TestBiodObserver observer;
  fake_biod_client_.AddObserver(&observer);
  EXPECT_EQ(0u, GetRecordsForUser(kTestUserId).size());

  // Add two users, who have scanned three fingers between the two of them.
  const std::string kUserOne = std::string(kTestUserId) + "1";
  const std::string kUserTwo = std::string(kTestUserId) + "2";

  const std::string kLabelOne = std::string(kTestLabel) + "1";
  const std::string kLabelTwo = std::string(kTestLabel) + "2";
  const std::string kLabelThree = std::string(kTestLabel) + "3";

  // Generate 2 test fingerprints per user.
  const std::vector<std::string>& kUser1Finger1 = GenerateTestFingerprint(2);
  const std::vector<std::string>& kUser1Finger2 = GenerateTestFingerprint(2);
  const std::vector<std::string>& kUser2Finger1 = GenerateTestFingerprint(2);
  const std::vector<std::string>& kUser2Finger2 = GenerateTestFingerprint(2);

  EnrollFingerprint(kUserOne, kLabelOne, kUser1Finger1);
  EnrollFingerprint(kUserOne, kLabelTwo, kUser1Finger2);
  // User one has registered finger two twice.
  EnrollFingerprint(kUserOne, kLabelThree, kUser1Finger2);
  EnrollFingerprint(kUserTwo, kLabelOne, kUser2Finger1);
  EnrollFingerprint(kUserTwo, kLabelTwo, kUser2Finger2);
  // User two has allowed user one to unlock their account with their first
  // finger.
  EnrollFingerprint(kUserTwo, kLabelThree, kUser1Finger1);

  dbus::ObjectPath returned_path;
  fake_biod_client_.StartAuthSession(
      base::Bind(&test_utils::CopyObjectPath, &returned_path));
  task_runner_->RunUntilIdle();
  EXPECT_NE(returned_path, dbus::ObjectPath());

  // Verify that if a user registers the same finger to two different labels,
  // both ObjectPath that maps to the labels are returned as matches.
  std::vector<dbus::ObjectPath> record_paths_user1 =
      GetRecordsForUser(kUserOne);
  EXPECT_EQ(3u, record_paths_user1.size());

  AuthScanMatches expected_auth_scans_matches;
  expected_auth_scans_matches[kUserOne] = {record_paths_user1[1],
                                           record_paths_user1[2]};
  fake_biod_client_.SendAuthScanDone(kUser1Finger2[0], SCAN_RESULT_SUCCESS);
  EXPECT_EQ(expected_auth_scans_matches, observer.last_auth_scan_matches());

  // Verify that a fingerprint associated with one user and one label returns a
  // match with one user and one ObjectPath that maps to that label.
  std::vector<dbus::ObjectPath> record_paths_user2 =
      GetRecordsForUser(kUserTwo);
  EXPECT_EQ(3u, record_paths_user2.size());

  expected_auth_scans_matches.clear();
  expected_auth_scans_matches[kUserTwo] = {record_paths_user2[0]};
  fake_biod_client_.SendAuthScanDone(kUser2Finger1[0], SCAN_RESULT_SUCCESS);
  EXPECT_EQ(expected_auth_scans_matches, observer.last_auth_scan_matches());

  // Verify if two users register the same fingerprint, the matches contain
  // both users.
  expected_auth_scans_matches.clear();
  expected_auth_scans_matches[kUserOne] = {record_paths_user1[0]};
  expected_auth_scans_matches[kUserTwo] = {record_paths_user2[2]};
  fake_biod_client_.SendAuthScanDone(kUser1Finger1[0], SCAN_RESULT_SUCCESS);
  EXPECT_EQ(expected_auth_scans_matches, observer.last_auth_scan_matches());

  // Verify if a unregistered finger is scanned, the matches are empty.
  expected_auth_scans_matches.clear();
  fake_biod_client_.SendAuthScanDone("Unregistered", SCAN_RESULT_SUCCESS);
  EXPECT_EQ(expected_auth_scans_matches, observer.last_auth_scan_matches());
}

TEST_F(FakeBiodClientTest, TestGetRecordsForUser) {
  // Verify that initially |kTestUserId| will have no fingerprints.
  EXPECT_EQ(0u, GetRecordsForUser(kTestUserId).size());

  // Verify that after enrolling 2 fingerprints, a GetRecords call return 2
  // items.
  EnrollNTestFingerprints(kTestUserId, kTestLabel, GenerateTestFingerprint(2),
                          2);
  EXPECT_EQ(2u, GetRecordsForUser(kTestUserId).size());

  // Verify that GetRecords call for a user with no registered fingerprints
  // should return 0 items.
  EXPECT_EQ(0u, GetRecordsForUser("noRegisteredFingerprints@gmail.com").size());
}

TEST_F(FakeBiodClientTest, TestDestroyingRecords) {
  // Verify that after enrolling 2 fingerprints and destroying them, 0
  // fingerprints will remain.
  EnrollNTestFingerprints(kTestUserId, kTestLabel, GenerateTestFingerprint(2),
                          2);
  EXPECT_EQ(2u, GetRecordsForUser(kTestUserId).size());
  fake_biod_client_.DestroyAllRecords(EmptyVoidDBusMethodCallback());
  EXPECT_EQ(0u, GetRecordsForUser(kTestUserId).size());
}

TEST_F(FakeBiodClientTest, TestGetAndSetRecordLabels) {
  const std::string kLabelOne = "Finger 1";
  const std::string kLabelTwo = "Finger 2";

  EnrollFingerprint(kTestUserId, kLabelOne, GenerateTestFingerprint(2));
  EnrollFingerprint(kTestUserId, kLabelTwo, GenerateTestFingerprint(2));
  EXPECT_EQ(2u, GetRecordsForUser(kTestUserId).size());
  std::vector<dbus::ObjectPath> enrollment_paths;
  fake_biod_client_.GetRecordsForUser(
      kTestUserId,
      base::Bind(&test_utils::CopyObjectPathArray, &enrollment_paths));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(2u, enrollment_paths.size());

  // Verify the labels we get using GetLabel are the same as the one we
  // originally set.
  std::string returned_str;
  fake_biod_client_.RequestRecordLabel(
      enrollment_paths[0], base::Bind(&test_utils::CopyString, &returned_str));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(kLabelOne, returned_str);

  returned_str = "";
  fake_biod_client_.RequestRecordLabel(
      enrollment_paths[1], base::Bind(&test_utils::CopyString, &returned_str));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(kLabelTwo, returned_str);

  // Verify that by setting a new label, getting the label will return the value
  // of the new label.
  const std::string kNewLabelTwo = "Finger 2 New";
  fake_biod_client_.SetRecordLabel(enrollment_paths[1], kNewLabelTwo,
                                   EmptyVoidDBusMethodCallback());
  fake_biod_client_.RequestRecordLabel(
      enrollment_paths[1], base::Bind(&test_utils::CopyString, &returned_str));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(kNewLabelTwo, returned_str);
}

}  // namespace chromeos
