// Copyright 2021 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 "rmad/utils/json_store.h"

#include <memory>
#include <string>
#include <utility>

#include <base/check.h>
#include <base/files/file_util.h>
#include <base/json/json_file_value_serializer.h>
#include <base/json/json_string_value_serializer.h>
#include <base/logging.h>
#include <base/notreached.h>
#include <base/values.h>

namespace rmad {

namespace {

JsonStore::ReadError TranslateJsonFileReadErrors(const base::Value* value,
                                                 int error_code) {
  if (!value) {
    switch (error_code) {
      case JSONFileValueDeserializer::JSON_ACCESS_DENIED:
        return JsonStore::READ_ERROR_FILE_ACCESS_DENIED;
      case JSONFileValueDeserializer::JSON_CANNOT_READ_FILE:
        return JsonStore::READ_ERROR_FILE_OTHER;
      case JSONFileValueDeserializer::JSON_FILE_LOCKED:
        return JsonStore::READ_ERROR_FILE_LOCKED;
      case JSONFileValueDeserializer::JSON_NO_SUCH_FILE:
        return JsonStore::READ_ERROR_NO_SUCH_FILE;
      default:
        // JSONParser::JsonParseError errors.
        return JsonStore::READ_ERROR_JSON_PARSE;
    }
  }
  if (!value->is_dict())
    return JsonStore::READ_ERROR_JSON_TYPE;
  return JsonStore::READ_ERROR_NONE;
}

bool SerializeValue(const base::Value& value, std::string* output) {
  JSONStringValueSerializer serializer(output);
  serializer.set_pretty_print(false);
  return serializer.Serialize(value);
}

}  // namespace

struct JsonStore::ReadResult {
 public:
  ReadResult() = default;
  ~ReadResult() = default;

  std::unique_ptr<base::Value> value;
  JsonStore::ReadError read_error;
};

JsonStore::JsonStore(const base::FilePath& file_path)
    : file_path_(file_path),
      data_(base::Value::Type::DICTIONARY),
      read_error_(READ_ERROR_NONE),
      read_only_(false) {
  InitFromFile();
}

bool JsonStore::SetValue(const std::string& key, base::Value&& value) {
  DCHECK(data_.is_dict());
  if (read_only_) {
    return false;
  }
  const base::Value* result = data_.FindKey(key);
  if (!result || *result != value) {
    data_.SetKey(key, std::move(value));
    return WriteToFile();
  }
  return true;
}

bool JsonStore::GetValue(const std::string& key,
                         const base::Value** value) const {
  DCHECK(data_.is_dict());
  const base::Value* result = data_.FindKey(key);
  if (!result) {
    return false;
  }
  if (value) {
    *value = result;
  }
  return true;
}

bool JsonStore::GetValue(const std::string& key, base::Value* value) const {
  const base::Value* result;
  if (!GetValue(key, &result)) {
    return false;
  }
  if (value) {
    *value = result->Clone();
  }
  return true;
}

base::Value JsonStore::GetValues() const {
  return data_.Clone();
}

bool JsonStore::Clear() {
  data_ = base::Value(base::Value::Type::DICTIONARY);
  return WriteToFile();
}

void JsonStore::InitFromFile() {
  std::unique_ptr<JsonStore::ReadResult> read_result = ReadFromFile();
  read_error_ = read_result->read_error;
  switch (read_error_) {
    case READ_ERROR_JSON_PARSE:
    case READ_ERROR_JSON_TYPE:
    case READ_ERROR_FILE_ACCESS_DENIED:
    case READ_ERROR_FILE_LOCKED:
    case READ_ERROR_FILE_OTHER:
      read_only_ = true;
      break;
    case READ_ERROR_NONE:
      data_ = std::move(*read_result->value);
      break;
    case READ_ERROR_NO_SUCH_FILE:
      data_ = base::Value(base::Value::Type::DICTIONARY);
      break;
    case READ_ERROR_MAX_ENUM:
      NOTREACHED();
      break;
  }
  DLOG(INFO) << "JsonStore::InitFromFile complete.";
}

std::unique_ptr<JsonStore::ReadResult> JsonStore::ReadFromFile() {
  auto read_result = std::make_unique<JsonStore::ReadResult>();
  JSONFileValueDeserializer deserializer(file_path_);
  int error_code = 0;
  std::string error_msg;
  read_result->value = deserializer.Deserialize(&error_code, &error_msg);
  read_result->read_error =
      TranslateJsonFileReadErrors(read_result->value.get(), error_code);
  return read_result;
}

bool JsonStore::WriteToFile() {
  if (read_only_)
    return false;

  std::string serialized_data;
  if (!SerializeValue(data_, &serialized_data)) {
    DLOG(ERROR) << "JsonStore::WriteToFile failed to serialize data.";
    return false;
  }
  return base::WriteFile(file_path_, serialized_data);
}

}  // namespace rmad
