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

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

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/values.h>

namespace biod {

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

const std::string& FakeBiometricsManager::Record::GetUserId() const {
  InternalRecord* internal = GetInternal();
  CHECK(internal)
      << "Attempted to get user ID for invalid BiometricsManager Record";
  return internal->user_id;
}

const std::string& FakeBiometricsManager::Record::GetLabel() const {
  InternalRecord* internal = GetInternal();
  CHECK(internal)
      << "Attempted to get label for invalid BiometricsManager Record";
  return internal->label;
}

bool FakeBiometricsManager::Record::SetLabel(std::string label) {
  InternalRecord* internal = GetInternal();
  if (internal) {
    internal->label = std::move(label);
    // Set label by overwriting records in file.
    return biometrics_manager_->biod_storage_.WriteRecord(
        *this,
        std::unique_ptr<base::Value>(new base::StringValue("Hello, world!")));
  }
  LOG(ERROR) << "Attempt to set label for invalid BiometricsManager Record";
  return false;
}

bool FakeBiometricsManager::Record::Remove() {
  // Delete one record.
  if (biometrics_manager_->biod_storage_.DeleteRecord(
          biometrics_manager_->records_[id_].user_id, id_)) {
    return biometrics_manager_->records_.erase(id_) > 0;
  } else {
    return false;
  }
}

FakeBiometricsManager::InternalRecord*
FakeBiometricsManager::Record::GetInternal() const {
  if (!biometrics_manager_)
    return nullptr;
  auto internal_record = biometrics_manager_->records_.find(id_);
  if (internal_record == biometrics_manager_->records_.end())
    return nullptr;
  return &internal_record->second;
}

FakeBiometricsManager::FakeBiometricsManager()
    : session_weak_factory_(this),
      weak_factory_(this),
      biod_storage_(kFakeBiometricsManagerName,
                    base::Bind(&FakeBiometricsManager::LoadRecord,
                               base::Unretained(this))) {
  const char kFakeInputPath[] = "/tmp/fake_biometric";
  base::DeleteFile(base::FilePath(kFakeInputPath), false);
  CHECK_EQ(mkfifo(kFakeInputPath, 0600), 0)
      << "Failed to create FakeBiometricsManager input";
  // The pipe gets opened read/write to avoid triggering a constant stream of
  // POLLHUP after the pipe is opened writable and closed. The pipe is never
  // actually written to here.
  fake_input_ = base::ScopedFD(open(kFakeInputPath, O_RDWR | O_NONBLOCK));
  CHECK_GE(fake_input_.get(), 0)
      << "Failed to open FakeBiometricsManager input";

  fd_watcher_ = std::make_unique<base::MessageLoopForIO::FileDescriptorWatcher>(
      FROM_HERE);

  CHECK(base::MessageLoopForIO::current()->WatchFileDescriptor(
      fake_input_.get(),
      true,
      base::MessageLoopForIO::WATCH_READ,
      fd_watcher_.get(),
      this))
      << "Failed to watch FakeBiometricsManager input";
}

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

BiometricsManager::EnrollSession FakeBiometricsManager::StartEnrollSession(
    std::string user_id, std::string label) {
  if (mode_ == Mode::kNone) {
    mode_ = Mode::kEnrollSession;
    next_internal_record_ = {std::move(user_id), std::move(label)};
    return BiometricsManager::EnrollSession(session_weak_factory_.GetWeakPtr());
  }
  return BiometricsManager::EnrollSession();
}

BiometricsManager::AuthSession FakeBiometricsManager::StartAuthSession() {
  if (mode_ == Mode::kNone) {
    mode_ = Mode::kAuthSession;
    return BiometricsManager::AuthSession(session_weak_factory_.GetWeakPtr());
  }
  return BiometricsManager::AuthSession();
}

std::vector<std::unique_ptr<BiometricsManager::Record>>
FakeBiometricsManager::GetRecords() {
  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 FakeBiometricsManager::DestroyAllRecords() {
  // Enumerate through records_ and delete each record.
  bool delete_all_records = true;
  for (auto& record_pair : records_) {
    delete_all_records &= biod_storage_.DeleteRecord(record_pair.second.user_id,
                                                     record_pair.first);
  }
  records_.clear();
  return delete_all_records;
}

void FakeBiometricsManager::RemoveRecordsFromMemory() {
  records_.clear();
}

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

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

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

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

void FakeBiometricsManager::EndEnrollSession() {
  CHECK(mode_ == Mode::kEnrollSession);
  session_weak_factory_.InvalidateWeakPtrs();
  mode_ = Mode::kNone;
}

void FakeBiometricsManager::EndAuthSession() {
  CHECK(mode_ == Mode::kAuthSession);
  session_weak_factory_.InvalidateWeakPtrs();
  mode_ = Mode::kNone;
}

void FakeBiometricsManager::OnFileCanWriteWithoutBlocking(int fd) {
  NOTREACHED();
}

void FakeBiometricsManager::OnFileCanReadWithoutBlocking(int fd) {
  // We scan the stream for the magic bytes in case the previous input command
  // was not the correct length or malformed for whatever reason. This must be
  // done a single byte at a time because the input stream of bytes is totally
  // unaligned. Reading the length of magic bytes at once might consume some
  // garbage data and the start of the magic bytes, but that would fail to
  // validate, and subsequent reads would never see that correct instance of
  // magic bytes.
  size_t magic_index = 0;
  const uint8_t magic_start[] = {FAKE_BIOMETRIC_MAGIC_BYTES};
  while (magic_index < sizeof(magic_start)) {
    uint8_t magic;
    if (read(fd, &magic, sizeof(magic)) != sizeof(magic))
      return;
    if (magic == magic_start[magic_index])
      magic_index++;
    else
      magic_index = 0;
  }

  uint8_t cmd;
  if (read(fd, &cmd, sizeof(cmd)) != sizeof(cmd))
    return;
  switch (cmd) {
    case 'A': {
      uint8_t res_code;
      if (read(fd, &res_code, sizeof(res_code)) != sizeof(res_code))
        return;
      ScanResult res = static_cast<ScanResult>(res_code);

      uint8_t match_user_count;
      if (read(fd, &match_user_count, sizeof(match_user_count)) !=
          sizeof(match_user_count))
        return;

      BiometricsManager::AttemptMatches matches;
      for (uint8_t match_index = 0; match_index < match_user_count;
           match_index++) {
        uint8_t user_id_size;
        if (read(fd, &user_id_size, sizeof(user_id_size)) !=
            sizeof(user_id_size))
          return;

        std::string user_id(user_id_size, '\0');
        if (read(fd, &user_id.front(), user_id.size()) != user_id.size())
          return;

        // These record IDs are interpreted as record identifiers by biod and
        // its clients.
        std::vector<std::string>& record_ids = matches[user_id];

        uint8_t record_id_count;
        if (read(fd, &record_id_count, sizeof(record_id_count)) !=
            sizeof(record_id_count))
          return;

        for (uint8_t record_id_index = 0; record_id_index < record_id_count;
             record_id_index++) {
          uint8_t record_id_size;
          if (read(fd, &record_id_size, sizeof(record_id_size)) !=
              sizeof(record_id_size))
            return;

          std::string record_id(record_id_size, '\0');
          int ret = read(fd, &record_id.front(), record_id.size());
          if (ret != record_id.size()) {
            LOG(ERROR) << "failed to read record id " << errno;
            return;
          }

          record_ids.emplace_back(std::move(record_id));
        }
        std::string record_ids_joined;
        for (const auto& record_id : record_ids) {
          record_ids_joined += " \"" + record_id + "\"";
        }
        LOG(INFO) << "Recognized User " << user_id
                  << " with record ids:" << record_ids_joined;
      }

      if (!on_auth_scan_done_.is_null() && mode_ == Mode::kAuthSession)
        on_auth_scan_done_.Run(res, matches);
      return;
    }
    case 'S': {
      uint8_t res_code;
      if (read(fd, &res_code, sizeof(res_code)) != sizeof(res_code))
        return;
      ScanResult res = static_cast<ScanResult>(res_code);

      uint8_t done;
      if (read(fd, &done, sizeof(done)) != sizeof(done))
        return;

      LOG(INFO) << "Scan result " << static_cast<int>(res_code) << " done "
                << static_cast<bool>(done);
      if (mode_ == Mode::kEnrollSession) {
        if (done) {
          std::string record_id(biod_storage_.GenerateNewRecordId());

          records_[record_id] = std::move(next_internal_record_);
          Record current_record(weak_factory_.GetWeakPtr(), record_id);

          if (!biod_storage_.WriteRecord(
                  current_record,
                  std::unique_ptr<base::Value>(
                      new base::StringValue("Hello, world!")))) {
            records_.erase(record_id);
          }
          mode_ = Mode::kNone;
          session_weak_factory_.InvalidateWeakPtrs();
        }

        if (!on_enroll_scan_done_.is_null()) {
          BiometricsManager::EnrollStatus enroll_status = {done > 0, -1};
          on_enroll_scan_done_.Run(res, enroll_status);
        }
      }
      return;
    }
    case 'F':
      LOG(INFO) << "Fake failure";
      if (!on_session_failed_.is_null())
        on_session_failed_.Run();
  }
}

bool FakeBiometricsManager::LoadRecord(const std::string& user_id,
                                       const std::string& label,
                                       const std::string& record_id,
                                       const base::Value& data) {
  InternalRecord internal_record = {user_id, label};
  records_[record_id] = std::move(internal_record);
  LOG(INFO) << "Load record " << record_id << " from disk.";
  return true;
}
}  // namespace biod
