// Copyright 2016 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.

#ifndef BIOD_BIOD_STORAGE_H_
#define BIOD_BIOD_STORAGE_H_

#include <memory>
#include <optional>
#include <string>
#include <unordered_set>
#include <vector>

#include <base/base64.h>
#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/values.h>
#include <brillo/secure_blob.h>
#include <brillo/scoped_umask.h>

#include "biod/biometrics_manager.h"
#include "biod/biometrics_manager_record.h"

namespace biod {

// Version of the record format.
constexpr int kRecordFormatVersion = 2;
constexpr int kRecordFormatVersionNoValidationValue = 1;

class BiodStorageInterface {
 public:
  struct RecordMetadata {
    /** Record file's scheme version. */
    int record_format_version;
    /** Record/fingerprint-template's UUID. */
    std::string record_id;
    /** Sanitized user session ID. */
    std::string user_id;
    /** User supplied description of finger. */
    std::string label;
    /** Positive match secrect validation value. */
    std::vector<uint8_t> validation_val;

    bool operator==(const RecordMetadata& rhs) const {
      return std::tie(this->record_format_version, this->validation_val,
                      this->record_id, this->user_id, this->label) ==
             std::tie(rhs.record_format_version, rhs.validation_val,
                      rhs.record_id, rhs.user_id, rhs.label);
    }

    bool operator!=(const RecordMetadata& rhs) const { return !(*this == rhs); }

    const std::string GetValidationValBase64() const {
      std::string validation_val_base64(validation_val.begin(),
                                        validation_val.end());
      base::Base64Encode(validation_val_base64, &validation_val_base64);
      return validation_val_base64;
    }

    bool IsValidUTF8() const {
      if (!base::IsStringUTF8(label)) {
        LOG(ERROR) << "Label is not valid UTF8";
        return false;
      }

      if (!base::IsStringUTF8(record_id)) {
        LOG(ERROR) << "Record ID is not valid UTF8";
        return false;
      }

      if (!base::IsStringUTF8(GetValidationValBase64())) {
        LOG(ERROR) << "Validation value is not valid UTF8";
        return false;
      }

      if (!base::IsStringUTF8(user_id)) {
        LOG(ERROR) << "User ID is not valid UTF8";
        return false;
      }

      return true;
    }
  };

  struct Record {
    RecordMetadata metadata;
    // "data" is base64 encoded.
    std::string data;
    bool valid = true;

    bool operator==(const Record& rhs) const {
      // Please note that |valid| is not taken into account when comparing
      // Record structures.
      return std::tie(this->metadata, this->data) ==
             std::tie(rhs.metadata, rhs.data);
    }

    bool operator!=(const Record& rhs) const { return !(*this == rhs); }
  };

  virtual ~BiodStorageInterface() = default;

  virtual void SetRootPathForTesting(const base::FilePath& root_path) = 0;
  virtual base::FilePath GetRecordFilename(
      const BiodStorageInterface::RecordMetadata& record_metadata) = 0;
  virtual bool WriteRecord(
      const BiodStorageInterface::RecordMetadata& record_metadata,
      base::Value data) = 0;
  virtual std::vector<Record> ReadRecords(
      const std::unordered_set<std::string>& user_ids) = 0;
  virtual std::vector<Record> ReadRecordsForSingleUser(
      const std::string& user_id) = 0;
  virtual std::optional<Record> ReadSingleRecord(
      const std::string& user_id, const std::string& record_id) = 0;
  virtual bool DeleteRecord(const std::string& user_id,
                            const std::string& record_id) = 0;
  virtual void set_allow_access(bool allow_access) = 0;
};

class BiodStorage : public BiodStorageInterface {
 public:
  // Constructor sets the file path to be
  // /run/daemon-store/biod/<user_id>/<biometrics_manager_name>/<record_id>,
  // which is bound to
  // /home/root/<user_id>/biod/<biometrics_manager_name>/<record_id>.
  explicit BiodStorage(const std::string& biometrics_manager_name);

  // Set root path to a different path for testing purpose only.
  void SetRootPathForTesting(const base::FilePath& root_path) override;

  /**
   * Get the file name for a given record. Intended to be used for testing.
   *
   * @param record
   * @return Full path on success. Empty path on failure.
   */
  base::FilePath GetRecordFilename(
      const BiodStorageInterface::RecordMetadata& record_metadata) override;

  // Write one record to file in per user stateful. This is called whenever
  // we enroll a new record.
  bool WriteRecord(const BiodStorageInterface::RecordMetadata& record_metadata,
                   base::Value data) override;

  // Read validation value from |record_dictionary| and store in |output|.
  static std::unique_ptr<std::vector<uint8_t>> ReadValidationValueFromRecord(
      const base::Value& record_dictionary,
      const base::FilePath& record_path);

  // Read all records from file for all users in the set. Called whenever biod
  // starts or when a new user logs in.
  std::vector<Record> ReadRecords(
      const std::unordered_set<std::string>& user_ids) override;

  // Read all records from disk for a single user. Uses a file enumerator to
  // enumerate through all record files. Called whenever biod starts or when
  // a new user logs in.
  std::vector<Record> ReadRecordsForSingleUser(
      const std::string& user_id) override;

  // Read a single record from disk and return it. If record doesn't exist
  // then std::nullopt is returned.
  std::optional<Record> ReadSingleRecord(const std::string& user_id,
                                         const std::string& record_id) override;

  // Delete one record file. User will be able to do this via UI. True if
  // this record does not exist on disk.
  bool DeleteRecord(const std::string& user_id,
                    const std::string& record_id) override;

  // Generate a uuid with guid.h for each record. Uuid is 128 bit number,
  // which is then turned into a string of format
  // xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx, where x is a lowercase hex number.
  static std::string GenerateNewRecordId();

  // Set the |allow_access_| which determines whether the backing storage
  // location can be accessed or not. Depending on the mounting mechanism and
  // namespace restrictions, the mounts might not be visible until after
  // certain points of the user flow (like successful login) are complete.
  void set_allow_access(bool allow_access) override {
    allow_access_ = allow_access;
  }

 private:
  // It reads single record from provided path. If record doesn't exist then
  // std::nullopt is returned. If record is invalid then |valid| field in the
  // Record structure will be set to false.
  std::optional<Record> ReadRecordFromPath(const base::FilePath& record_path);
  base::FilePath root_path_;
  std::string biometrics_manager_name_;
  bool allow_access_;
};
}  // namespace biod

#endif  // BIOD_BIOD_STORAGE_H_
