// Copyright 2017 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/biod_storage.h"

#include <algorithm>
#include <unordered_set>
#include <vector>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <testing/gtest/include/gtest/gtest.h>
#include <base/strings/string_util.h>

namespace biod {

namespace {

const char kBiometricsManagerName[] = "BiometricsManager";

const base::FilePath kFilePath("TestFile");

constexpr int kInvalidRecordFormatVersion = -1;

const char kRecordId1[] = "00000000_0000_0000_0000_000000000001";
const char kUserId1[] = "0000000000000000000000000000000000000001";
const char kLabel1[] = "record1";
const std::vector<uint8_t> kValidationVal1 = {0x00, 0x01};
const char kData1[] = "Hello, world1!";

const char kRecordId2[] = "00000000_0000_0000_0000_000000000002";
const char kUserId2[] = "0000000000000000000000000000000000000002";
const char kLabel2[] = "record2";
const std::vector<uint8_t> kValidationVal2 = {0x00, 0x02};
const char kData2[] = "Hello, world2!";

const char kRecordId3[] = "00000000_0000_0000_0000_000000000003";
const char kLabel3[] = "record3";
const std::vector<uint8_t> kValidationVal3 = {0x00, 0x03};
const char kData3[] = "Hello, world3!";

constexpr int kPermissions600 =
    base::FILE_PERMISSION_READ_BY_USER | base::FILE_PERMISSION_WRITE_BY_USER;
constexpr int kPermissions700 = base::FILE_PERMISSION_USER_MASK;

const char kInvalidUTF8[] = "\xed\xa0\x80\xed\xbf\xbf";

// Flag to control whether to run tests with positive match secret support.
// This can't be a member of the test fixture because it's accessed in the
// TestRecord class in anonymous namespace.
bool test_record_supports_positive_match_secret = true;

class TestRecord : public BiometricsManager::Record {
 public:
  TestRecord(const std::string& id,
             const std::string& user_id,
             const std::string& label,
             const std::vector<uint8_t>& validation_val,
             const std::string& data)
      : id_(id),
        user_id_(user_id),
        label_(label),
        validation_val_(validation_val),
        data_(data) {}

  // BiometricsManager::Record overrides:
  const std::string& GetId() const override { return id_; }
  const std::string& GetUserId() const override { return user_id_; }
  const std::string& GetLabel() const override { return label_; }
  const std::vector<uint8_t>& GetValidationVal() const override {
    return validation_val_;
  }
  const std::string& GetData() const { return data_; }
  bool SetLabel(std::string label) override { return true; }
  bool Remove() override { return true; }
  bool SupportsPositiveMatchSecret() const override {
    return test_record_supports_positive_match_secret;
  }
  bool NeedsNewValidationValue() const override { return false; }

  void ClearValidationValue() { validation_val_.clear(); }

  friend bool operator==(const TestRecord& lhs, const TestRecord& rhs) {
    return lhs.id_ == rhs.id_ && lhs.user_id_ == rhs.user_id_ &&
           lhs.validation_val_ == rhs.validation_val_ &&
           lhs.label_ == rhs.label_ && lhs.data_ == rhs.data_;
  }
  friend inline bool operator!=(const TestRecord& lhs, const TestRecord& rhs) {
    return !(lhs == rhs);
  }

 private:
  std::string id_;
  std::string user_id_;
  std::string label_;
  std::vector<uint8_t> validation_val_;
  std::string data_;
};
}  // namespace

class BiodStorageBaseTest : public ::testing::Test {
 public:
  BiodStorageBaseTest() {
    CHECK(temp_dir_.CreateUniqueTempDir());
    root_path_ = temp_dir_.GetPath().AppendASCII("biod_storage_unittest_root");
    biod_storage_.reset(new BiodStorage(
        kBiometricsManagerName,
        base::Bind(&BiodStorageBaseTest::LoadRecord, base::Unretained(this))));
    // Since there is no session manager, allow accesses by default.
    biod_storage_->set_allow_access(true);
    biod_storage_->SetRootPathForTesting(root_path_);
  }

  ~BiodStorageBaseTest() override {
    EXPECT_TRUE(base::DeleteFile(temp_dir_.GetPath(), true));
  }

  base::DictionaryValue CreateRecordDictionary(
      const std::vector<uint8_t>& validation_val) {
    base::DictionaryValue record_dictionary;
    std::string validation_value_str(validation_val.begin(),
                                     validation_val.end());
    base::Base64Encode(validation_value_str, &validation_value_str);
    record_dictionary.SetString("match_validation_value", validation_value_str);
    return record_dictionary;
  }

 protected:
  base::ScopedTempDir temp_dir_;
  base::FilePath root_path_;
  std::unique_ptr<BiodStorage> biod_storage_;
  std::vector<TestRecord> records_;

 private:
  // LoadRecord is a callback passed to biod_storage_. It gets called when
  // biod_storage_ reads a record from storage. It loads the new record into
  // records_.
  bool LoadRecord(int record_format_version,
                  const std::string& user_id,
                  const std::string& label,
                  const std::string& record_id,
                  const std::vector<uint8_t>& validation_val,
                  const base::Value& data_value) {
    std::string data;
    data_value.GetAsString(&data);
    records_.push_back(
        TestRecord(record_id, user_id, label, validation_val, data));
    return true;
  }

  DISALLOW_COPY_AND_ASSIGN(BiodStorageBaseTest);
};

class BiodStorageTest : public BiodStorageBaseTest,
                        public ::testing::WithParamInterface<bool> {
 public:
  BiodStorageTest() { test_record_supports_positive_match_secret = GetParam(); }
};

TEST_P(BiodStorageTest, WriteAndReadRecords) {
  const std::vector<uint8_t> kEmpty;
  const std::vector<TestRecord> kRecords = {
      TestRecord(
          kRecordId1, kUserId1, kLabel1,
          test_record_supports_positive_match_secret ? kValidationVal1 : kEmpty,
          kData1),
      TestRecord(
          kRecordId2, kUserId2, kLabel2,
          test_record_supports_positive_match_secret ? kValidationVal2 : kEmpty,
          kData2),
      TestRecord(
          kRecordId3, kUserId2, kLabel3,
          test_record_supports_positive_match_secret ? kValidationVal3 : kEmpty,
          kData3)};

  // Write the record.
  for (auto const& record : kRecords) {
    EXPECT_TRUE(biod_storage_->WriteRecord(
        record, std::make_unique<base::Value>(record.GetData())));
  }

  // Read the record.
  std::unordered_set<std::string> user_ids({kUserId1, kUserId2});
  EXPECT_TRUE(biod_storage_->ReadRecords(user_ids));
  EXPECT_TRUE(
      std::is_permutation(kRecords.begin(), kRecords.end(), records_.begin()));
}

TEST_F(BiodStorageBaseTest, WriteRecord_InvalidAbsolutePath) {
  auto record =
      TestRecord(kRecordId1, "/absolutepath", kLabel1, kValidationVal1, kData1);

  EXPECT_FALSE(biod_storage_->WriteRecord(
      record, std::make_unique<base::Value>(record.GetData())));
}

TEST_F(BiodStorageBaseTest, WriteRecord_RecordIdNotUTF8) {
  EXPECT_FALSE(base::IsStringUTF8(kInvalidUTF8));

  auto record =
      TestRecord(kInvalidUTF8, kUserId1, kLabel1, kValidationVal1, kData1);

  EXPECT_FALSE(record.IsValidUTF8());
  EXPECT_FALSE(biod_storage_->WriteRecord(
      record, std::make_unique<base::Value>(record.GetData())));
}

TEST_F(BiodStorageBaseTest, WriteRecord_UserIdNotUTF8) {
  EXPECT_FALSE(base::IsStringUTF8(kInvalidUTF8));

  auto record =
      TestRecord(kRecordId1, kInvalidUTF8, kLabel1, kValidationVal1, kData1);

  EXPECT_FALSE(record.IsValidUTF8());
  EXPECT_FALSE(biod_storage_->WriteRecord(
      record, std::make_unique<base::Value>(record.GetData())));
}

TEST_F(BiodStorageBaseTest, WriteRecord_LabelNotUTF8) {
  EXPECT_FALSE(base::IsStringUTF8(kInvalidUTF8));

  auto record =
      TestRecord(kRecordId1, kUserId1, kInvalidUTF8, kValidationVal1, kData1);

  EXPECT_FALSE(record.IsValidUTF8());
  EXPECT_FALSE(biod_storage_->WriteRecord(
      record, std::make_unique<base::Value>(record.GetData())));
}

TEST_F(BiodStorageBaseTest, WriteRecord_CheckUmask) {
  auto record =
      TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1);

  const base::FilePath kRecordStorageFilename =
      root_path_.Append("biod")
          .Append(record.GetUserId())
          .Append(kBiometricsManagerName)
          .Append("Record" + record.GetId());

  ASSERT_FALSE(base::PathExists(kRecordStorageFilename));
  ASSERT_FALSE(base::PathExists(kRecordStorageFilename.DirName()));

  EXPECT_TRUE(biod_storage_->WriteRecord(
      record, std::make_unique<base::Value>(record.GetData())));

  // Check permissions of directory
  int actual_permissions;
  EXPECT_TRUE(base::GetPosixFilePermissions(kRecordStorageFilename.DirName(),
                                            &actual_permissions));
  EXPECT_EQ(kPermissions700, actual_permissions);

  // Check permissions of record
  EXPECT_TRUE(base::GetPosixFilePermissions(kRecordStorageFilename,
                                            &actual_permissions));
  EXPECT_EQ(kPermissions600, actual_permissions);
}

TEST_P(BiodStorageTest, DeleteRecord) {
  const std::vector<uint8_t> kEmpty;
  const TestRecord kRecord(
      kRecordId1, kUserId1, kLabel1,
      test_record_supports_positive_match_secret ? kValidationVal1 : kEmpty,
      kData1);

  // Delete a non-existent record.
  EXPECT_TRUE(biod_storage_->DeleteRecord(kUserId1, kRecordId1));

  EXPECT_TRUE(biod_storage_->WriteRecord(
      kRecord, std::make_unique<base::Value>(kRecord.GetData())));

  // Check this record is properly written.
  std::unordered_set<std::string> user_ids({kUserId1});
  EXPECT_TRUE(biod_storage_->ReadRecords(user_ids));
  ASSERT_FALSE(records_.empty());
  ASSERT_EQ(1u, records_.size());
  EXPECT_EQ(records_[0], kRecord);

  records_.clear();

  EXPECT_TRUE(biod_storage_->DeleteRecord(kUserId1, kRecordId1));

  // Check this record is properly deleted.
  EXPECT_TRUE(biod_storage_->ReadRecords(user_ids));
  EXPECT_TRUE(records_.empty());
}

TEST_F(BiodStorageBaseTest, GenerateNewRecordId) {
  // Check the two record ids are different.
  std::string record_id1(biod_storage_->GenerateNewRecordId());
  std::string record_id2(biod_storage_->GenerateNewRecordId());
  EXPECT_NE(record_id1, record_id2);
}

TEST_F(BiodStorageBaseTest, TestEqualOperator) {
  EXPECT_EQ(TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1),
            TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1));

  EXPECT_NE(TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal1, kData1),
            TestRecord(kRecordId1, kUserId1, kLabel1, kValidationVal2, kData1));
}

TEST_F(BiodStorageBaseTest, TestReadValidationValueFromRecord) {
  auto record_dictionary = CreateRecordDictionary(kValidationVal1);
  auto ret = biod_storage_->ReadValidationValueFromRecord(
      kRecordFormatVersion, &record_dictionary, kFilePath);
  EXPECT_TRUE(ret != nullptr);
  EXPECT_EQ(*ret, kValidationVal1);
}

TEST_F(BiodStorageBaseTest, TestReadValidationValueFromRecordOldVersion) {
  auto record_dictionary = CreateRecordDictionary(kValidationVal1);
  std::vector<uint8_t> empty;
  auto ret = biod_storage_->ReadValidationValueFromRecord(
      kRecordFormatVersionNoValidationValue, &record_dictionary, kFilePath);
  EXPECT_TRUE(ret != nullptr);
  EXPECT_EQ(*ret, empty);
}

TEST_F(BiodStorageBaseTest, TestReadValidationValueFromRecordInvalidVersion) {
  auto record_dictionary = CreateRecordDictionary(kValidationVal1);
  std::vector<uint8_t> empty;
  auto ret = biod_storage_->ReadValidationValueFromRecord(
      kInvalidRecordFormatVersion, &record_dictionary, kFilePath);
  EXPECT_EQ(ret, nullptr);
}

INSTANTIATE_TEST_SUITE_P(RecordsSupportPositiveMatchSecret,
                         BiodStorageTest,
                         ::testing::Values(true, false));
}  // namespace biod
