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

#include "biod/fpc_biometrics_manager.h"

#include <algorithm>

#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <base/base64.h>
#include <base/bind.h>
#include <base/logging.h>
#include <base/strings/string_piece.h>
#include <base/threading/thread_task_runner_handle.h>

#include "biod/fpc/fp_sensor.h"

namespace biod {

class FpcBiometricsManager::SensorLibrary {
 public:
  ~SensorLibrary();

  static std::unique_ptr<SensorLibrary> Open(
      const std::shared_ptr<BioLibrary>& bio_lib, int fd);

  BioEnrollment BeginEnrollment();
  std::tuple<int, BioImage> AcquireImage();
  bool WaitFingerUp();
  bool Cancel();

 private:
  using fp_sensor_open_fp = int (*)(int fd);
  using fp_sensor_close_fp = int (*)(void);
  using fp_sensor_get_model_fp = int (*)(uint32_t* vendor_id,
                                         uint32_t* product_id,
                                         uint32_t* model_id,
                                         uint32_t* version);
  using fp_sensor_get_pixel_format_fp = int (*)(uint32_t* pixel_format);
  using fp_sensor_get_image_data_size_fp = ssize_t (*)(void);
  using fp_sensor_get_image_dimensions_fp = int (*)(uint32_t* width,
                                                    uint32_t* height);
  using fp_sensor_acquire_image_fp = int (*)(uint8_t* image_data, size_t size);
  using fp_sensor_wait_finger_up_fp = int (*)(void);
  using fp_sensor_cancel_fp = int (*)(void);

  explicit SensorLibrary(const std::shared_ptr<BioLibrary>& bio_lib)
      : bio_lib_(bio_lib) {}
  bool Init(int fd);

  fp_sensor_open_fp open_;
  fp_sensor_close_fp close_;
  fp_sensor_get_model_fp get_model_;
  fp_sensor_get_pixel_format_fp get_pixel_format_;
  fp_sensor_get_image_data_size_fp get_image_data_size_;
  fp_sensor_get_image_dimensions_fp get_image_dimensions_;
  fp_sensor_acquire_image_fp acquire_image_;
  fp_sensor_wait_finger_up_fp wait_finger_up_;
  fp_sensor_cancel_fp cancel_;

  std::shared_ptr<BioLibrary> bio_lib_;
  bool needs_close_ = false;
  size_t image_data_size_ = 0;
  BioSensor bio_sensor_;

  DISALLOW_COPY_AND_ASSIGN(SensorLibrary);
};

FpcBiometricsManager::SensorLibrary::~SensorLibrary() {
  if (needs_close_)
    close_();
}

std::unique_ptr<FpcBiometricsManager::SensorLibrary>
FpcBiometricsManager::SensorLibrary::Open(
    const std::shared_ptr<BioLibrary>& bio_lib, int fd) {
  std::unique_ptr<SensorLibrary> lib(new SensorLibrary(bio_lib));
  if (!lib->Init(fd))
    return nullptr;
  return lib;
}

BioEnrollment FpcBiometricsManager::SensorLibrary::BeginEnrollment() {
  return bio_sensor_.BeginEnrollment();
}

std::tuple<int, BioImage> FpcBiometricsManager::SensorLibrary::AcquireImage() {
  std::vector<uint8_t> image_data(image_data_size_);
  int acquire_result = acquire_image_(image_data.data(), image_data.size());
  if (acquire_result)
    return std::tuple<int, BioImage>(acquire_result, BioImage());

  BioImage image = bio_sensor_.CreateImage();
  if (!image || !image.SetData(&image_data)) {
    LOG(ERROR) << "Failed to construct BioImage for image acquired.";
    return std::tuple<int, BioImage>(-ENOMEM, BioImage());
  }

  return std::tuple<int, BioImage>(0 /* success */, std::move(image));
}

bool FpcBiometricsManager::SensorLibrary::WaitFingerUp() {
  int ret = wait_finger_up_();
  if (ret)
    LOG(ERROR) << "Failed to wait for finger up: " << ret;
  return ret == 0;
}

bool FpcBiometricsManager::SensorLibrary::Cancel() {
  int ret = cancel_();
  if (ret)
    LOG(ERROR) << "Failed to cancel FPC sensor operation: " << ret;
  return ret == 0;
}

bool FpcBiometricsManager::SensorLibrary::Init(int fd) {
#define SENSOR_SYM(x)                                                  \
  do {                                                                 \
    x##_ = bio_lib_->GetFunction<fp_sensor_##x##_fp>("fp_sensor_" #x); \
    if (!x##_) {                                                       \
      LOG(ERROR) << #x " is missing from library";                     \
      return false;                                                    \
    }                                                                  \
  } while (0)

  // Here we use the very same shared object loaded by BioLibrary to pull out
  // some private functions that interface with the FPC sensor.
  SENSOR_SYM(open);
  SENSOR_SYM(close);
  SENSOR_SYM(get_model);
  SENSOR_SYM(get_pixel_format);
  SENSOR_SYM(get_image_data_size);
  SENSOR_SYM(get_image_dimensions);
  SENSOR_SYM(acquire_image);
  SENSOR_SYM(wait_finger_up);
  SENSOR_SYM(cancel);

#undef SENSOR_SYM

  int ret = open_(fd);
  if (ret) {
    LOG(ERROR) << "Failed to open sensor library: " << ret;
    return false;
  }
  needs_close_ = true;

  BioSensor::Model model;
  ret = get_model_(
      &model.vendor_id, &model.product_id, &model.model_id, &model.version);
  if (ret) {
    LOG(ERROR) << "Failed to get sensor model: " << ret;
    return false;
  }

  uint32_t pixel_format;
  ret = get_pixel_format_(&pixel_format);
  if (ret) {
    LOG(ERROR) << "Failed to get sensor pixel format: " << ret;
    return false;
  }

  ssize_t image_data_size = get_image_data_size_();
  if (image_data_size <= 0) {
    LOG(ERROR) << "Failed to get sensor image data size: " << image_data_size;
    return false;
  }
  image_data_size_ = image_data_size;

  uint32_t width, height;
  ret = get_image_dimensions_(&width, &height);
  if (ret) {
    LOG(ERROR) << "Failed to get sensor image dimensions: " << ret;
    return false;
  }

  LOG(INFO) << "FPC Sensor Info ";
  LOG(INFO) << "  Vendor ID  : " << model.vendor_id;
  LOG(INFO) << "  Product ID : " << model.product_id;
  LOG(INFO) << "  Model ID   : " << model.model_id;
  LOG(INFO) << "  Version    : " << model.version;
  LOG(INFO) << "FPC Image Info ";
  // Prints the pixel format in FOURCC format.
  const uint32_t a = pixel_format;
  LOG(INFO) << "  Pixel Format     : " << static_cast<char>(a)
            << static_cast<char>(a >> 8) << static_cast<char>(a >> 16)
            << static_cast<char>(a >> 24);
  LOG(INFO) << "  Image Data Size  : " << image_data_size;
  LOG(INFO) << "  Image Dimensions : " << width << "x" << height;

  bio_sensor_ = bio_lib_->CreateSensor();
  if (!bio_sensor_)
    return false;

  if (!bio_sensor_.SetModel(model))
    return false;

  if (!bio_sensor_.SetFormat(pixel_format))
    return false;

  if (!bio_sensor_.SetSize(width, height))
    return false;

  return true;
}

const std::string& FpcBiometricsManager::Record::GetId() const {
  return id_;
}

const std::string& FpcBiometricsManager::Record::GetUserId() const {
  CHECK(WithInternal([this](RecordIterator i) {
    this->local_user_id_ = i->second.user_id;
  })) << ": Attempted to get user ID for invalid BiometricsManager Record";
  return local_user_id_;
}

const std::string& FpcBiometricsManager::Record::GetLabel() const {
  CHECK(WithInternal([this](RecordIterator i) {
    this->local_label_ = i->second.label;
  })) << ": Attempted to get label for invalid BiometricsManager Record";
  return local_label_;
}

bool FpcBiometricsManager::Record::SetLabel(std::string label) {
  std::string old_label;
  std::vector<uint8_t> serialized_tmpl;
  CHECK(WithInternal([&](RecordIterator i) {
    old_label = i->second.label;
    i->second.label = std::move(label);
    (i->second.tmpl).Serialize(&serialized_tmpl);
  })) << ": Attempted to reset label for invalid BiometricsManager Record";

  if (!biometrics_manager_->WriteRecord(
          *this, serialized_tmpl.data(), serialized_tmpl.size())) {
    CHECK(WithInternal(
        [&](RecordIterator i) { i->second.label = std::move(old_label); }));
    return false;
  }
  return true;
}

bool FpcBiometricsManager::Record::Remove() {
  if (!biometrics_manager_)
    return false;
  if (!biometrics_manager_->biod_storage_.DeleteRecord(GetUserId(), GetId())) {
    return false;
  }
  return WithInternal(
      [this](RecordIterator i) { biometrics_manager_->records_.erase(i); });
}

int FpcBiometricsManager::g_sensor_fd = -1;

std::unique_ptr<BiometricsManager> FpcBiometricsManager::Create() {
  std::unique_ptr<FpcBiometricsManager> biometrics_manager(
      new FpcBiometricsManager);
  if (!biometrics_manager->Init())
    return nullptr;

  return std::unique_ptr<BiometricsManager>(std::move(biometrics_manager));
}

BiometricType FpcBiometricsManager::GetType() {
  return BIOMETRIC_TYPE_FINGERPRINT;
}

BiometricsManager::EnrollSession FpcBiometricsManager::StartEnrollSession(
    std::string user_id, std::string label) {
  if (running_task_)
    return BiometricsManager::EnrollSession();

  std::shared_ptr<BioTemplate> tmpl = std::make_shared<BioTemplate>();

  kill_task_ = false;
  bool task_will_run = sensor_thread_.task_runner()->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&FpcBiometricsManager::DoEnrollSessionTask,
                 base::Unretained(this),
                 base::ThreadTaskRunnerHandle::Get(),
                 tmpl),
      base::Bind(&FpcBiometricsManager::OnEnrollSessionComplete,
                 weak_factory_.GetWeakPtr(),
                 std::move(user_id),
                 std::move(label),
                 tmpl));

  if (!task_will_run) {
    LOG(ERROR) << "Failed to schedule EnrollSession task";
    return BiometricsManager::EnrollSession();
  }

  // Note that the On*Complete function sets running_task_ to false on this
  // thread's message loop, so setting it here does not result in a race
  // condition.
  running_task_ = true;

  return BiometricsManager::EnrollSession(session_weak_factory_.GetWeakPtr());
}

BiometricsManager::AuthSession FpcBiometricsManager::StartAuthSession() {
  if (running_task_)
    return BiometricsManager::AuthSession();

  std::shared_ptr<std::unordered_set<std::string>> updated_record_ids =
      std::make_shared<std::unordered_set<std::string>>();

  kill_task_ = false;
  bool task_will_run = sensor_thread_.task_runner()->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&FpcBiometricsManager::DoAuthSessionTask,
                 base::Unretained(this),
                 base::ThreadTaskRunnerHandle::Get(),
                 updated_record_ids),
      base::Bind(&FpcBiometricsManager::OnAuthSessionComplete,
                 weak_factory_.GetWeakPtr(),
                 updated_record_ids));

  if (!task_will_run) {
    LOG(ERROR) << "Failed to schedule AuthSession task";
    return BiometricsManager::AuthSession();
  }

  // Note that the On*Complete function sets running_task_ to false on this
  // thread's message loop, so setting it here does not result in a race
  // condition.
  running_task_ = true;

  return BiometricsManager::AuthSession(session_weak_factory_.GetWeakPtr());
}

std::vector<std::unique_ptr<BiometricsManager::Record>>
FpcBiometricsManager::GetRecords() {
  base::AutoLock guard(records_lock_);
  std::vector<std::unique_ptr<BiometricsManager::Record>> records(
      records_.size());
  std::transform(records_.begin(),
                 records_.end(),
                 records.begin(),
                 [this](decltype(records_)::value_type& record) {
                   return std::unique_ptr<BiometricsManager::Record>(
                       new Record(weak_factory_.GetWeakPtr(), record.first));
                 });
  return records;
}

bool FpcBiometricsManager::DestroyAllRecords() {
  base::AutoLock guard(records_lock_);

  // Enumerate through records_ and delete each record.
  bool delete_all_records = true;
  for (auto& record_pair : records_) {
    std::string record_id(record_pair.first);
    std::string user_id(record_pair.second.user_id);
    delete_all_records &= biod_storage_.DeleteRecord(user_id, record_id);
  }
  records_.clear();
  return delete_all_records;
}

void FpcBiometricsManager::RemoveRecordsFromMemory() {
  base::AutoLock guard(records_lock_);
  records_.clear();
}

bool FpcBiometricsManager::ReadRecords(
    const std::unordered_set<std::string>& user_ids) {
  return biod_storage_.ReadRecords(user_ids);
}

void FpcBiometricsManager::SetEnrollScanDoneHandler(
    const BiometricsManager::EnrollScanDoneCallback& on_enroll_scan_done) {
  on_enroll_scan_done_ = on_enroll_scan_done;
}

void FpcBiometricsManager::SetAuthScanDoneHandler(
    const BiometricsManager::AuthScanDoneCallback& on_auth_scan_done) {
  on_auth_scan_done_ = on_auth_scan_done;
}

void FpcBiometricsManager::SetSessionFailedHandler(
    const BiometricsManager::SessionFailedCallback& on_session_failed) {
  on_session_failed_ = on_session_failed;
}

void FpcBiometricsManager::EndEnrollSession() {
  KillSensorTask();
}

void FpcBiometricsManager::EndAuthSession() {
  KillSensorTask();
}

void FpcBiometricsManager::KillSensorTask() {
  {
    base::AutoLock guard(kill_task_lock_);
    kill_task_ = true;
  }
  sensor_lib_->Cancel();
}

FpcBiometricsManager::FpcBiometricsManager()
    : sensor_thread_("fpc_sensor"),
      session_weak_factory_(this),
      weak_factory_(this),
      biod_storage_(kFpcBiometricsManagerName,
                    base::Bind(&FpcBiometricsManager::LoadRecord,
                               base::Unretained(this))) {}

FpcBiometricsManager::~FpcBiometricsManager() {}

bool FpcBiometricsManager::Init() {
  const char kFpcSensorPath[] = "/dev/fpc_sensor0";
  sensor_fd_ = base::ScopedFD(open(kFpcSensorPath, O_RDWR));
  g_sensor_fd = sensor_fd_.get();
  if (sensor_fd_.get() < 0) {
    LOG(ERROR) << "Failed to open " << kFpcSensorPath;
    return false;
  }

  const char kFpcLibName[] = "/opt/fpc/lib/libfpsensor.so";
  bio_lib_ = BioLibrary::Load(base::FilePath(kFpcLibName));
  if (!bio_lib_)
    return false;

  sensor_lib_ = SensorLibrary::Open(bio_lib_, sensor_fd_.get());
  if (!sensor_lib_)
    return false;

  if (!sensor_thread_.Start()) {
    LOG(ERROR) << "Failed to start sensor thread";
    return false;
  }

  return true;
}

void FpcBiometricsManager::OnEnrollScanDone(
    ScanResult result, const BiometricsManager::EnrollStatus& enroll_status) {
  if (!on_enroll_scan_done_.is_null())
    on_enroll_scan_done_.Run(result, enroll_status);
}

void FpcBiometricsManager::OnAuthScanDone(
    ScanResult result, const BiometricsManager::AttemptMatches& matches) {
  if (!on_auth_scan_done_.is_null())
    on_auth_scan_done_.Run(result, matches);
}

void FpcBiometricsManager::OnSessionFailed() {
  if (!on_session_failed_.is_null())
    on_session_failed_.Run();
}

FpcBiometricsManager::ScanData FpcBiometricsManager::ScanImage() {
  DCHECK(sensor_thread_.task_runner()->RunsTasksOnCurrentThread());
  bool success = sensor_lib_->WaitFingerUp();
  {
    base::AutoLock guard(kill_task_lock_);
    if (kill_task_)
      return ScanData(ScanData::Killed());
  }

  if (!success)
    return ScanData();

  int acquire_result, attempts = 0;
  BioImage image;
  // If the finger is positioned slightly off the sensor, retry a few times
  // before failing. Typically the user has put their finger down and is now
  // moving their finger to the correct position on the sensor. Instead of
  // immediately failing, retry until we get a good image.
  // Retry 20 times, which takes ~5s on Eve, before giving up and sending an
  // error back to the user. Assume ~1s for user noticing that no matching
  // happened, some time to move the finger on the sensor to allow a full
  // capture and another 1s for the second matching attempt. 5s gives a bit of
  // margin to avoid interrupting the user while they're moving the finger on
  // the sensor.
  const int kMaxPartialAttempts = 20;
  do {
    std::tie(acquire_result, image) = sensor_lib_->AcquireImage();
    {
      base::AutoLock guard(kill_task_lock_);
      if (kill_task_)
        return ScanData(ScanData::Killed());
    }
    ++attempts;
  } while (acquire_result == FP_SENSOR_LOW_SENSOR_COVERAGE &&
           attempts < kMaxPartialAttempts);

  switch (acquire_result) {
    case 0:
      break;
    case FP_SENSOR_TOO_FAST:
      return ScanData(ScanResult::SCAN_RESULT_TOO_FAST);
    case FP_SENSOR_LOW_IMAGE_QUALITY:
      return ScanData(ScanResult::SCAN_RESULT_INSUFFICIENT);
    case FP_SENSOR_LOW_SENSOR_COVERAGE:
      return ScanData(ScanResult::SCAN_RESULT_PARTIAL);
    default:
      LOG(ERROR) << "Unexpected result from acquiring image: "
                 << acquire_result;
      return ScanData();
  }

  return ScanData(std::move(image));
}

void FpcBiometricsManager::DoEnrollSessionTask(
    const TaskRunnerRef& task_runner,
    const std::shared_ptr<BioTemplate>& tmpl) {
  DCHECK(sensor_thread_.task_runner()->RunsTasksOnCurrentThread());

  if (kill_task_)
    return;

  BioEnrollment enrollment = sensor_lib_->BeginEnrollment();
  if (!enrollment)
    return;

  for (;;) {
    ScanData scan = ScanImage();

    // The previous function can return early if this task was killed, or there
    // was an unrecoverable hardware failure.
    if (scan.killed || !scan.success)
      return;

    ScanResult scan_result = scan.result;
    if (scan) {
      int add_result = enrollment.AddImage(scan.image);
      switch (add_result) {
        case BIO_ENROLLMENT_OK:
          break;
        case BIO_ENROLLMENT_IMMOBILE:
          scan_result = ScanResult::SCAN_RESULT_IMMOBILE;
          break;
        case BIO_ENROLLMENT_LOW_COVERAGE:
          scan_result = ScanResult::SCAN_RESULT_PARTIAL;
          break;
        case BIO_ENROLLMENT_LOW_QUALITY:
          scan_result = ScanResult::SCAN_RESULT_INSUFFICIENT;
          break;
        default:
          LOG(ERROR) << "Unexpected result from add image: " << add_result;
          return;
      }
    }

    int complete_result = enrollment.IsComplete();
    if (complete_result < 0) {
      LOG(ERROR) << "Failed to get enrollment completion: " << complete_result;
      return;
    } else if (complete_result == 1) {
      *tmpl = enrollment.Finish();
      return;
    } else {
      BiometricsManager::EnrollStatus enroll_status = {
          false, enrollment.GetPercentComplete()};

      // Notice we will only ever post the on_enroll_scan_done task on an
      // incomplete enrollment. The complete on_enroll_scan_done task is only
      // posted after the enrollment is added to the enrollments(records) map,
      // which is done only on the main thread's message loop.
      bool task_will_run = task_runner->PostTask(
          FROM_HERE,
          base::Bind(&FpcBiometricsManager::OnEnrollScanDone,
                     base::Unretained(this),
                     scan_result,
                     enroll_status));
      if (!task_will_run) {
        LOG(ERROR) << "Failed to schedule EnrollScanDone callback";
        return;
      }
    }
  }
}

void FpcBiometricsManager::OnEnrollSessionComplete(
    std::string user_id,
    std::string label,
    const std::shared_ptr<BioTemplate>& tmpl) {
  OnTaskComplete();

  if (kill_task_)
    return;

  // Remember tmpl stores a shared pointer to a /pointer/ which contains the
  // actual result.
  if (!*tmpl.get()) {
    OnSessionFailed();
    return;
  }

  std::vector<uint8_t> serialized_tmpl;
  if (!tmpl->Serialize(&serialized_tmpl)) {
    OnSessionFailed();
    return;
  }

  std::string record_id(biod_storage_.GenerateNewRecordId());
  {
    base::AutoLock guard(records_lock_);
    records_.emplace(
        record_id,
        InternalRecord{
            std::move(user_id), std::move(label), std::move(*tmpl.get())});
  }
  Record current_record(weak_factory_.GetWeakPtr(), record_id);
  if (!WriteRecord(
          current_record, serialized_tmpl.data(), serialized_tmpl.size())) {
    {
      base::AutoLock guard(records_lock_);
      records_.erase(record_id);
    }
    OnSessionFailed();
    return;
  }

  BiometricsManager::EnrollStatus enroll_status = {true, 100};
  OnEnrollScanDone(ScanResult::SCAN_RESULT_SUCCESS, enroll_status);
}

void FpcBiometricsManager::DoAuthSessionTask(
    const TaskRunnerRef& task_runner,
    std::shared_ptr<std::unordered_set<std::string>> updated_record_ids) {
  DCHECK(sensor_thread_.task_runner()->RunsTasksOnCurrentThread());

  if (kill_task_)
    return;

  BiometricsManager::AttemptMatches matches;

  for (;;) {
    ScanData scan = ScanImage();

    // The previous function can return early if this task was killed, or there
    // was an unrecoverable hardware failure.
    if (scan.killed || !scan.success)
      break;

    ScanResult result = scan.result;
    if (result == ScanResult::SCAN_RESULT_SUCCESS) {
      matches.clear();

      base::AutoLock guard(records_lock_);
      for (auto& kv : records_) {
        InternalRecord& record = kv.second;

        int match_result = record.tmpl.MatchImage(scan.image);
        switch (match_result) {
          case BIO_TEMPLATE_NO_MATCH:
            break;
          case BIO_TEMPLATE_MATCH_UPDATED:  // record.tmpl got updated
            updated_record_ids->insert(kv.first);
          case BIO_TEMPLATE_MATCH: {
            auto emplace_result =
                matches.emplace(record.user_id, std::vector<std::string>());
            emplace_result.first->second.emplace_back(kv.first);
            break;
          }
          case BIO_TEMPLATE_LOW_QUALITY:
            result = ScanResult::SCAN_RESULT_INSUFFICIENT;
            break;
          case BIO_TEMPLATE_LOW_COVERAGE:
            result = ScanResult::SCAN_RESULT_PARTIAL;
            break;
          default:
            LOG(ERROR) << "Unexpected result from matching templates: "
                       << match_result;
            return;
        }
      }
    }

    // Assuming there was at least one match, we don't want to bother the user
    // with error messages.
    if (!matches.empty())
      result = ScanResult::SCAN_RESULT_SUCCESS;

    bool task_will_run =
        task_runner->PostTask(FROM_HERE,
                              base::Bind(&FpcBiometricsManager::OnAuthScanDone,
                                         base::Unretained(this),
                                         result,
                                         std::move(matches)));
    if (!task_will_run) {
      LOG(ERROR) << "Failed to schedule AuthScanDone callback";
      return;
    }
  }
}

void FpcBiometricsManager::OnAuthSessionComplete(
    std::shared_ptr<std::unordered_set<std::string>> updated_record_ids) {
  OnTaskComplete();

  // AuthSession never ends except on error or being killed. If no kill
  // signal was given, we can assume failure.
  if (!kill_task_)
    OnSessionFailed();

  for (const std::string& record_id : *updated_record_ids) {
    InternalRecord& record = records_[record_id];

    std::vector<uint8_t> serialized_tmpl;
    if (!record.tmpl.Serialize(&serialized_tmpl)) {
      LOG(ERROR) << "Cannot update record " << record_id
                 << " in storage during AuthSession because template "
                    "serialization failed.";
      continue;
    }

    Record current_record(weak_factory_.GetWeakPtr(), record_id);
    if (!WriteRecord(
            current_record, serialized_tmpl.data(), serialized_tmpl.size())) {
      LOG(ERROR) << "Cannot update record " << record_id
                 << " in storage during AuthSession because writing failed.";
    }
  }
}

void FpcBiometricsManager::OnTaskComplete() {
  session_weak_factory_.InvalidateWeakPtrs();
  running_task_ = false;
}

bool FpcBiometricsManager::LoadRecord(const std::string& user_id,
                                      const std::string& label,
                                      const std::string& record_id,
                                      const base::Value& data) {
  std::string tmpl_data_base64;
  if (!data.GetAsString(&tmpl_data_base64)) {
    LOG(ERROR) << "Cannot load data string from record " << record_id << ".";
    return false;
  }

  base::StringPiece tmpl_data_base64_sp(tmpl_data_base64);
  std::string tmpl_data_str;
  base::Base64Decode(tmpl_data_base64_sp, &tmpl_data_str);

  std::vector<uint8_t> tmpl_data_vector(tmpl_data_str.begin(),
                                        tmpl_data_str.end());
  BioTemplate tmpl(bio_lib_->DeserializeTemplate(tmpl_data_vector));
  InternalRecord internal_record = {user_id, label, std::move(tmpl)};
  {
    base::AutoLock guard(records_lock_);
    records_[record_id] = std::move(internal_record);
  }
  LOG(INFO) << "Load record " << record_id << " from disk.";
  return true;
}

bool FpcBiometricsManager::WriteRecord(const BiometricsManager::Record& record,
                                       uint8_t* tmpl_data,
                                       size_t tmpl_size) {
  base::StringPiece tmpl_sp(reinterpret_cast<char*>(tmpl_data), tmpl_size);
  std::string tmpl_base64;
  base::Base64Encode(tmpl_sp, &tmpl_base64);

  return biod_storage_.WriteRecord(
      record, std::unique_ptr<base::Value>(new base::StringValue(tmpl_base64)));
}

}  // namespace biod
