// 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_string_value_serializer.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/string_util.h>
#include <base/values.h>

namespace biod {

using base::FilePath;

namespace {
const char kRootPath[] = "/home/root";
const char kRecordFileName[] = "Record";
const char kBiod[] = "biod";
const char kLabel[] = "label";
const char kRecordId[] = "record_id";
const char kData[] = "data";
}

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

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) {
  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));

  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(record.GetUserId())
                                         .Append(kBiod)
                                         .Append(biometrics_manager_name_)
                                         .Append(kRecordFileName + record_id);
  if (!base::CreateDirectory(record_storage_filename.DirName())) {
    LOG(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) {
  FilePath biod_path =
      root_path_.Append(user_id).Append(kBiod).Append(biometrics_manager_name_);
  base::FileEnumerator enum_records(biod_path,
                                    false,
                                    base::FileEnumerator::FILES,
                                    FILE_PATH_LITERAL("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);
    json_deserializer.set_allow_trailing_comma(true);
    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) {
  FilePath record_storage_filename = root_path_.Append(user_id)
                                         .Append(kBiod)
                                         .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
