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

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

#include <algorithm>
#include <sstream>
#include <utility>

#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/important_file_writer.h>
#include <base/guid.h>
#include <base/json/json_reader.h>
#include <base/json/json_string_value_serializer.h>
#include <base/logging.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/string_util.h>
#include <base/values.h>

namespace biod {

using base::FilePath;

namespace {
constexpr char kDaemonStorePath[] = "/run/daemon-store";
constexpr char kRecordFileName[] = "Record";
constexpr char kBiod[] = "biod";

// Members of the JSON file.
constexpr char kBioManagerMember[] = "biomanager";
constexpr char kData[] = "data";
constexpr char kLabel[] = "label";
constexpr char kRecordId[] = "record_id";
constexpr char kVersionMember[] = "version";
// Version of the file format.
constexpr int kFormatVersion = 1;
}  // namespace

BiodStorage::BiodStorage(const std::string& biometrics_manager_name,
                         const ReadRecordsCallback& load_record)
    : root_path_(kDaemonStorePath),
      biometrics_manager_name_(biometrics_manager_name),
      load_record_(load_record),
      allow_access_(false) {}

void BiodStorage::SetRootPathForTesting(const base::FilePath& root_path) {
  root_path_ = root_path;
}

bool BiodStorage::WriteRecord(const BiometricsManager::Record& record,
                              std::unique_ptr<base::Value> data) {
  if (!allow_access_) {
    LOG(ERROR) << "Access to the storage mounts not allowed.";
    return false;
  }

  const std::string& record_id(record.GetId());
  base::DictionaryValue record_value;
  record_value.SetString(kLabel, record.GetLabel());
  record_value.SetString(kRecordId, record_id);
  record_value.Set(kData, std::move(data));
  record_value.SetInteger(kVersionMember, kFormatVersion);
  record_value.SetString(kBioManagerMember, biometrics_manager_name_);

  std::string json_string;
  JSONStringValueSerializer json_serializer(&json_string);
  if (!json_serializer.Serialize(record_value)) {
    LOG(ERROR) << "Failed to serialize record with id " << record_id
               << " to JSON.";
    return false;
  }

  std::unique_ptr<ScopedUmask> owner_only_umask(new ScopedUmask(~(0700)));

  FilePath record_storage_filename = root_path_.Append(kBiod)
                                         .Append(record.GetUserId())
                                         .Append(biometrics_manager_name_)
                                         .Append(kRecordFileName + record_id);
  if (!base::CreateDirectory(record_storage_filename.DirName())) {
    PLOG(ERROR) << "Cannot create directory: "
                << record_storage_filename.DirName().value() << ".";
    return false;
  }

  owner_only_umask.reset(new ScopedUmask(~(0600)));

  if (!base::ImportantFileWriter::WriteFileAtomically(record_storage_filename,
                                                      json_string)) {
    LOG(ERROR) << "Failed to write JSON file: "
               << record_storage_filename.value() << ".";
    return false;
  }
  LOG(INFO) << "Done writing record with id " << record_id
            << " to file successfully. ";
  return true;
}

bool BiodStorage::ReadRecords(const std::unordered_set<std::string>& user_ids) {
  bool read_records_from_all_users = true;
  for (const auto& user_id : user_ids) {
    read_records_from_all_users &= ReadRecordsForSingleUser(user_id);
  }
  return read_records_from_all_users;
}

bool BiodStorage::ReadRecordsForSingleUser(const std::string& user_id) {
  if (!allow_access_) {
    LOG(ERROR) << "Access to the storage mounts not yet allowed.";
    return false;
  }

  FilePath biod_path =
      root_path_.Append(kBiod).Append(user_id).Append(biometrics_manager_name_);
  base::FileEnumerator enum_records(biod_path, false,
                                    base::FileEnumerator::FILES, "Record*");
  bool read_all_records_successfully = true;
  for (FilePath record_path = enum_records.Next(); !record_path.empty();
       record_path = enum_records.Next()) {
    std::string json_string;
    if (!base::ReadFileToString(record_path, &json_string)) {
      LOG(ERROR) << "Failed to read the string from " << record_path.value()
                 << ".";
      read_all_records_successfully = false;
      continue;
    }

    JSONStringValueDeserializer json_deserializer(
        json_string, base::JSON_ALLOW_TRAILING_COMMAS);
    int error_code;
    std::string error_message;
    std::unique_ptr<base::Value> record_value(
        json_deserializer.Deserialize(&error_code, &error_message));

    if (!record_value) {
      LOG_IF(ERROR, error_code)
          << "Error in deserializing JSON from path " << record_path.value()
          << " with code " << error_code << ".";
      LOG_IF(ERROR, !error_message.empty())
          << "JSON error message: " << error_message << ".";
      read_all_records_successfully = false;
      continue;
    }

    base::DictionaryValue* record_dictionary;

    if (!record_value->GetAsDictionary(&record_dictionary)) {
      LOG(ERROR) << "Cannot cast " << record_path.value()
                 << " to a dictionary value.";
      read_all_records_successfully = false;
      continue;
    }

    std::string label;

    if (!record_dictionary->GetString(kLabel, &label)) {
      LOG(ERROR) << "Cannot read label from " << record_path.value() << ".";
      read_all_records_successfully = false;
      continue;
    }

    std::string record_id;

    if (!(record_dictionary->GetString(kRecordId, &record_id))) {
      LOG(ERROR) << "Cannot read record id from " << record_path.value() << ".";
      read_all_records_successfully = false;
      continue;
    }

    base::Value* data = nullptr;

    if (!(record_dictionary->Get(kData, &data))) {
      LOG(ERROR) << "Cannot read data from " << record_path.value() << ".";
      read_all_records_successfully = false;
      continue;
    }

    if (!load_record_.Run(user_id, label, record_id, *data)) {
      LOG(ERROR) << "Cannot load record from " << record_path.value() << ".";
      read_all_records_successfully = false;
      continue;
    }
  }
  return read_all_records_successfully;
}

bool BiodStorage::DeleteRecord(const std::string& user_id,
                               const std::string& record_id) {
  if (!allow_access_) {
    LOG(ERROR) << "Access to the storage mounts not yet allowed.";
    return false;
  }

  FilePath record_storage_filename = root_path_.Append(kBiod)
                                         .Append(user_id)
                                         .Append(biometrics_manager_name_)
                                         .Append(kRecordFileName + record_id);

  if (!base::PathExists(record_storage_filename)) {
    LOG(INFO) << "Trying to delete record " << record_id
              << " which does not exist on disk.";
    return true;
  }
  if (!base::DeleteFile(record_storage_filename, false)) {
    LOG(ERROR) << "Fail to delete record " << record_id << " from disk.";
    return false;
  }
  LOG(INFO) << "Done deleting record " << record_id << " from disk.";
  return true;
}

std::string BiodStorage::GenerateNewRecordId() {
  std::string record_id(base::GenerateGUID());
  // dbus member names only allow '_'
  std::replace(record_id.begin(), record_id.end(), '-', '_');
  return record_id;
}
}  // namespace biod
