// 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 "base/json/json_parser.h"
#include "base/logging.h"

namespace base {

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.";

JSONReader::JSONReader()
    : parser_(new internal::JSONParser(JSON_PARSE_RFC)) {
}

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

JSONReader::~JSONReader() {
}

// static
Value* JSONReader::Read(const StringPiece& json) {
  internal::JSONParser parser(JSON_PARSE_RFC);
  return parser.Parse(json);
}

// static
Value* JSONReader::Read(const StringPiece& json,
                        int options) {
  internal::JSONParser parser(options);
  return parser.Parse(json);
}

// static
Value* JSONReader::ReadAndReturnError(const StringPiece& json,
                                      int options,
                                      int* error_code_out,
                                      std::string* error_msg_out) {
  internal::JSONParser parser(options);
  Value* root = parser.Parse(json);
  if (root)
    return root;

  if (error_code_out)
    *error_code_out = parser.error_code();
  if (error_msg_out)
    *error_msg_out = parser.GetErrorMessage();

  return NULL;
}

// 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;
    default:
      NOTREACHED();
      return std::string();
  }
}

Value* JSONReader::ReadToValue(const std::string& json) {
  return parser_->Parse(json);
}

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

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

}  // namespace base
