// Copyright (c) 2012 The Chromium 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 "base/json/json_reader.h"

#include <utility>
#include <vector>

#include "base/json/json_parser.h"
#include "base/logging.h"
#include "base/values.h"

namespace base {

// Chosen to support 99.9% of documents found in the wild late 2016.
// http://crbug.com/673263
const int JSONReader::kStackMaxDepth = 200;

// Values 1000 and above are used by JSONFileValueSerializer::JsonFileError.
static_assert(JSONReader::JSON_PARSE_ERROR_COUNT < 1000,
              "JSONReader error out of bounds");

const char JSONReader::kInvalidEscape[] = "Invalid escape sequence.";
const char JSONReader::kSyntaxError[] = "Syntax error.";
const char JSONReader::kUnexpectedToken[] = "Unexpected token.";
const char JSONReader::kTrailingComma[] = "Trailing comma not allowed.";
const char JSONReader::kTooMuchNesting[] = "Too much nesting.";
const char JSONReader::kUnexpectedDataAfterRoot[] =
    "Unexpected data after root element.";
const char JSONReader::kUnsupportedEncoding[] =
    "Unsupported encoding. JSON must be UTF-8.";
const char JSONReader::kUnquotedDictionaryKey[] =
    "Dictionary keys must be quoted.";
const char JSONReader::kInputTooLarge[] = "Input string is too large (>2GB).";

JSONReader::JSONReader(int options, int max_depth)
    : parser_(new internal::JSONParser(options, max_depth)) {}

JSONReader::~JSONReader() = default;

// static
std::unique_ptr<Value> JSONReader::Read(std::string_view json,
                                        int options,
                                        int max_depth) {
  internal::JSONParser parser(options, max_depth);
  std::optional<Value> root = parser.Parse(json);
  return root ? std::make_unique<Value>(std::move(*root)) : nullptr;
}

// static
std::unique_ptr<Value> JSONReader::ReadAndReturnError(
    std::string_view json,
    int options,
    int* error_code_out,
    std::string* error_msg_out,
    int* error_line_out,
    int* error_column_out) {
  internal::JSONParser parser(options);
  std::optional<Value> root = parser.Parse(json);
  if (!root) {
    if (error_code_out)
      *error_code_out = parser.error_code();
    if (error_msg_out)
      *error_msg_out = parser.GetErrorMessage();
    if (error_line_out)
      *error_line_out = parser.error_line();
    if (error_column_out)
      *error_column_out = parser.error_column();
  }

  return root ? std::make_unique<Value>(std::move(*root)) : nullptr;
}

// static
std::string JSONReader::ErrorCodeToString(JsonParseError error_code) {
  switch (error_code) {
    case JSON_NO_ERROR:
      return std::string();
    case JSON_INVALID_ESCAPE:
      return kInvalidEscape;
    case JSON_SYNTAX_ERROR:
      return kSyntaxError;
    case JSON_UNEXPECTED_TOKEN:
      return kUnexpectedToken;
    case JSON_TRAILING_COMMA:
      return kTrailingComma;
    case JSON_TOO_MUCH_NESTING:
      return kTooMuchNesting;
    case JSON_UNEXPECTED_DATA_AFTER_ROOT:
      return kUnexpectedDataAfterRoot;
    case JSON_UNSUPPORTED_ENCODING:
      return kUnsupportedEncoding;
    case JSON_UNQUOTED_DICTIONARY_KEY:
      return kUnquotedDictionaryKey;
    case JSON_TOO_LARGE:
      return kInputTooLarge;
    case JSON_PARSE_ERROR_COUNT:
      break;
  }
  NOTREACHED();
  return std::string();
}

std::unique_ptr<Value> JSONReader::ReadToValue(std::string_view json) {
  std::optional<Value> value = parser_->Parse(json);
  return value ? std::make_unique<Value>(std::move(*value)) : nullptr;
}

JSONReader::JsonParseError JSONReader::error_code() const {
  return parser_->error_code();
}

std::string JSONReader::GetErrorMessage() const {
  return parser_->GetErrorMessage();
}

}  // namespace base
