// 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/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();
}

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
