// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/json_schema_compiler/manifest_parse_util.h"

#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"

namespace json_schema_compiler {
namespace manifest_parse_util {

namespace {

// Alias for a pointer to a base::Value const function which converts the
// base::Value into type T. This is used by ParseHelper below.
template <typename T>
using ValueTypeConverter = T (base::Value::*)() const;

template <typename T, typename U>
bool ParseHelper(const base::Value::Dict& dict,
                 base::StringPiece key,
                 base::Value::Type expected_type,
                 ValueTypeConverter<U> type_converter,
                 T& out,
                 std::u16string& error,
                 std::vector<base::StringPiece>& error_path_reversed) {
  DCHECK(type_converter);

  const base::Value* value =
      FindKeyOfType(dict, key, expected_type, error, error_path_reversed);
  if (!value)
    return false;

  out = (value->*type_converter)();
  return true;
}

}  // namespace

void PopulateInvalidEnumValueError(
    base::StringPiece key,
    base::StringPiece value,
    std::u16string& error,
    std::vector<base::StringPiece>& error_path_reversed) {
  DCHECK(error.empty());
  DCHECK(error_path_reversed.empty());

  error_path_reversed.push_back(key);
  error = base::ASCIIToUTF16(base::StringPrintf(
      "Specified value '%s' is invalid.", std::string(value).c_str()));
}

std::u16string GetArrayParseError(size_t error_index,
                                  const std::u16string& item_error) {
  return base::ASCIIToUTF16(
      base::StringPrintf("Parsing array failed at index %" PRIuS ": %s",
                         error_index, base::UTF16ToASCII(item_error).c_str()));
}

void PopulateFinalError(std::u16string& error,
                        std::vector<base::StringPiece>& error_path_reversed) {
  DCHECK(!error.empty());
  DCHECK(!error_path_reversed.empty());

  // Reverse the path to ensure the constituent keys are in the correct order.
  std::reverse(error_path_reversed.begin(), error_path_reversed.end());
  error = base::ASCIIToUTF16(
      base::StringPrintf("Error at key '%s'. %s",
                         base::JoinString(error_path_reversed, ".").c_str(),
                         base::UTF16ToASCII(error).c_str()));
}

const base::Value* FindKeyOfType(
    const base::Value::Dict& dict,
    base::StringPiece key,
    base::Value::Type expected_type,
    std::u16string& error,
    std::vector<base::StringPiece>& error_path_reversed) {
  DCHECK(error.empty());
  DCHECK(error_path_reversed.empty());

  const base::Value* value = dict.Find(key);
  if (!value) {
    error_path_reversed.push_back(key);
    error = u"Manifest key is required.";
    return nullptr;
  }

  if (value->type() != expected_type) {
    error_path_reversed.push_back(key);
    error = base::ASCIIToUTF16(
        base::StringPrintf("Type is invalid. Expected %s, found %s.",
                           base::Value::GetTypeName(expected_type),
                           base::Value::GetTypeName(value->type())));
    return nullptr;
  }

  return value;
}

bool ParseFromDictionary(const base::Value::Dict& dict,
                         base::StringPiece key,
                         int& out,
                         std::u16string& error,
                         std::vector<base::StringPiece>& error_path_reversed) {
  return ParseHelper(dict, key, base::Value::Type::INTEGER,
                     &base::Value::GetInt, out, error, error_path_reversed);
}

bool ParseFromDictionary(const base::Value::Dict& dict,
                         base::StringPiece key,
                         bool& out,
                         std::u16string& error,
                         std::vector<base::StringPiece>& error_path_reversed) {
  return ParseHelper(dict, key, base::Value::Type::BOOLEAN,
                     &base::Value::GetBool, out, error, error_path_reversed);
}

bool ParseFromDictionary(const base::Value::Dict& dict,
                         base::StringPiece key,
                         double& out,
                         std::u16string& error,
                         std::vector<base::StringPiece>& error_path_reversed) {
  return ParseHelper(dict, key, base::Value::Type::DOUBLE,
                     &base::Value::GetDouble, out, error, error_path_reversed);
}

bool ParseFromDictionary(const base::Value::Dict& dict,
                         base::StringPiece key,
                         std::string& out,
                         std::u16string& error,
                         std::vector<base::StringPiece>& error_path_reversed) {
  return ParseHelper(dict, key, base::Value::Type::STRING,
                     &base::Value::GetString, out, error, error_path_reversed);
}

}  // namespace manifest_parse_util
}  // namespace json_schema_compiler
