//===--------------------- JSON.cpp -----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Utility/JSON.h"

#include "lldb/Core/StreamString.h"
#include "lldb/Host/StringConvert.h"
#include "llvm/Support/ErrorHandling.h"
#include <limits.h>

using namespace lldb_private;

std::string JSONString::json_string_quote_metachars(const std::string &s) {
  if (s.find('"') == std::string::npos)
    return s;

  std::string output;
  const size_t s_size = s.size();
  const char *s_chars = s.c_str();
  for (size_t i = 0; i < s_size; i++) {
    unsigned char ch = *(s_chars + i);
    if (ch == '"') {
      output.push_back('\\');
    }
    output.push_back(ch);
  }
  return output;
}

JSONString::JSONString() : JSONValue(JSONValue::Kind::String), m_data() {}

JSONString::JSONString(const char *s)
    : JSONValue(JSONValue::Kind::String), m_data(s ? s : "") {}

JSONString::JSONString(const std::string &s)
    : JSONValue(JSONValue::Kind::String), m_data(s) {}

void JSONString::Write(Stream &s) {
  s.Printf("\"%s\"", json_string_quote_metachars(m_data).c_str());
}

uint64_t JSONNumber::GetAsUnsigned() const {
  switch (m_data_type) {
  case DataType::Unsigned:
    return m_data.m_unsigned;
  case DataType::Signed:
    return (uint64_t)m_data.m_signed;
  case DataType::Double:
    return (uint64_t)m_data.m_double;
  }
  llvm_unreachable("Unhandled data type");
}

int64_t JSONNumber::GetAsSigned() const {
  switch (m_data_type) {
  case DataType::Unsigned:
    return (int64_t)m_data.m_unsigned;
  case DataType::Signed:
    return m_data.m_signed;
  case DataType::Double:
    return (int64_t)m_data.m_double;
  }
  llvm_unreachable("Unhandled data type");
}

double JSONNumber::GetAsDouble() const {
  switch (m_data_type) {
  case DataType::Unsigned:
    return (double)m_data.m_unsigned;
  case DataType::Signed:
    return (double)m_data.m_signed;
  case DataType::Double:
    return m_data.m_double;
  }
  llvm_unreachable("Unhandled data type");
}

void JSONNumber::Write(Stream &s) {
  switch (m_data_type) {
  case DataType::Unsigned:
    s.Printf("%" PRIu64, m_data.m_unsigned);
    break;
  case DataType::Signed:
    s.Printf("%" PRId64, m_data.m_signed);
    break;
  case DataType::Double:
    s.Printf("%g", m_data.m_double);
    break;
  }
}

JSONTrue::JSONTrue() : JSONValue(JSONValue::Kind::True) {}

void JSONTrue::Write(Stream &s) { s.Printf("true"); }

JSONFalse::JSONFalse() : JSONValue(JSONValue::Kind::False) {}

void JSONFalse::Write(Stream &s) { s.Printf("false"); }

JSONNull::JSONNull() : JSONValue(JSONValue::Kind::Null) {}

void JSONNull::Write(Stream &s) { s.Printf("null"); }

JSONObject::JSONObject() : JSONValue(JSONValue::Kind::Object) {}

void JSONObject::Write(Stream &s) {
  bool first = true;
  s.PutChar('{');
  auto iter = m_elements.begin(), end = m_elements.end();
  for (; iter != end; iter++) {
    if (first)
      first = false;
    else
      s.PutChar(',');
    JSONString key(iter->first);
    JSONValue::SP value(iter->second);
    key.Write(s);
    s.PutChar(':');
    value->Write(s);
  }
  s.PutChar('}');
}

bool JSONObject::SetObject(const std::string &key, JSONValue::SP value) {
  if (key.empty() || nullptr == value.get())
    return false;
  m_elements[key] = value;
  return true;
}

JSONValue::SP JSONObject::GetObject(const std::string &key) {
  auto iter = m_elements.find(key), end = m_elements.end();
  if (iter == end)
    return JSONValue::SP();
  return iter->second;
}

JSONArray::JSONArray() : JSONValue(JSONValue::Kind::Array) {}

void JSONArray::Write(Stream &s) {
  bool first = true;
  s.PutChar('[');
  auto iter = m_elements.begin(), end = m_elements.end();
  for (; iter != end; iter++) {
    if (first)
      first = false;
    else
      s.PutChar(',');
    (*iter)->Write(s);
  }
  s.PutChar(']');
}

bool JSONArray::SetObject(Index i, JSONValue::SP value) {
  if (value.get() == nullptr)
    return false;
  if (i < m_elements.size()) {
    m_elements[i] = value;
    return true;
  }
  if (i == m_elements.size()) {
    m_elements.push_back(value);
    return true;
  }
  return false;
}

bool JSONArray::AppendObject(JSONValue::SP value) {
  if (value.get() == nullptr)
    return false;
  m_elements.push_back(value);
  return true;
}

JSONValue::SP JSONArray::GetObject(Index i) {
  if (i < m_elements.size())
    return m_elements[i];
  return JSONValue::SP();
}

JSONArray::Size JSONArray::GetNumElements() { return m_elements.size(); }

JSONParser::JSONParser(const char *cstr) : StringExtractor(cstr) {}

JSONParser::Token JSONParser::GetToken(std::string &value) {
  StreamString error;

  value.clear();
  SkipSpaces();
  const uint64_t start_index = m_index;
  const char ch = GetChar();
  switch (ch) {
  case '{':
    return Token::ObjectStart;
  case '}':
    return Token::ObjectEnd;
  case '[':
    return Token::ArrayStart;
  case ']':
    return Token::ArrayEnd;
  case ',':
    return Token::Comma;
  case ':':
    return Token::Colon;
  case '\0':
    return Token::EndOfFile;
  case 't':
    if (GetChar() == 'r')
      if (GetChar() == 'u')
        if (GetChar() == 'e')
          return Token::True;
    break;

  case 'f':
    if (GetChar() == 'a')
      if (GetChar() == 'l')
        if (GetChar() == 's')
          if (GetChar() == 'e')
            return Token::False;
    break;

  case 'n':
    if (GetChar() == 'u')
      if (GetChar() == 'l')
        if (GetChar() == 'l')
          return Token::Null;
    break;

  case '"': {
    while (1) {
      bool was_escaped = false;
      int escaped_ch = GetEscapedChar(was_escaped);
      if (escaped_ch == -1) {
        error.Printf(
            "error: an error occurred getting a character from offset %" PRIu64,
            start_index);
        value = std::move(error.GetString());
        return Token::Error;

      } else {
        const bool is_end_quote = escaped_ch == '"';
        const bool is_null = escaped_ch == 0;
        if (was_escaped || (!is_end_quote && !is_null)) {
          if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX) {
            value.append(1, (char)escaped_ch);
          } else {
            error.Printf("error: wide character support is needed for unicode "
                         "character 0x%4.4x at offset %" PRIu64,
                         escaped_ch, start_index);
            value = std::move(error.GetString());
            return Token::Error;
          }
        } else if (is_end_quote) {
          return Token::String;
        } else if (is_null) {
          value = "error: missing end quote for string";
          return Token::Error;
        }
      }
    }
  } break;

  case '-':
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9': {
    bool done = false;
    bool got_decimal_point = false;
    uint64_t exp_index = 0;
    bool got_int_digits = (ch >= '0') && (ch <= '9');
    bool got_frac_digits = false;
    bool got_exp_digits = false;
    while (!done) {
      const char next_ch = PeekChar();
      switch (next_ch) {
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        if (exp_index != 0) {
          got_exp_digits = true;
        } else if (got_decimal_point) {
          got_frac_digits = true;
        } else {
          got_int_digits = true;
        }
        ++m_index; // Skip this character
        break;

      case '.':
        if (got_decimal_point) {
          error.Printf("error: extra decimal point found at offset %" PRIu64,
                       start_index);
          value = std::move(error.GetString());
          return Token::Error;
        } else {
          got_decimal_point = true;
          ++m_index; // Skip this character
        }
        break;

      case 'e':
      case 'E':
        if (exp_index != 0) {
          error.Printf(
              "error: extra exponent character found at offset %" PRIu64,
              start_index);
          value = std::move(error.GetString());
          return Token::Error;
        } else {
          exp_index = m_index;
          ++m_index; // Skip this character
        }
        break;

      case '+':
      case '-':
        // The '+' and '-' can only come after an exponent character...
        if (exp_index == m_index - 1) {
          ++m_index; // Skip the exponent sign character
        } else {
          error.Printf("error: unexpected %c character at offset %" PRIu64,
                       next_ch, start_index);
          value = std::move(error.GetString());
          return Token::Error;
        }
        break;

      default:
        done = true;
        break;
      }
    }

    if (m_index > start_index) {
      value = m_packet.substr(start_index, m_index - start_index);
      if (got_decimal_point) {
        if (exp_index != 0) {
          // We have an exponent, make sure we got exponent digits
          if (got_exp_digits) {
            return Token::Float;
          } else {
            error.Printf("error: got exponent character but no exponent digits "
                         "at offset in float value \"%s\"",
                         value.c_str());
            value = std::move(error.GetString());
            return Token::Error;
          }
        } else {
          // No exponent, but we need at least one decimal after the decimal
          // point
          if (got_frac_digits) {
            return Token::Float;
          } else {
            error.Printf("error: no digits after decimal point \"%s\"",
                         value.c_str());
            value = std::move(error.GetString());
            return Token::Error;
          }
        }
      } else {
        // No decimal point
        if (got_int_digits) {
          // We need at least some integer digits to make an integer
          return Token::Integer;
        } else {
          error.Printf("error: no digits negate sign \"%s\"", value.c_str());
          value = std::move(error.GetString());
          return Token::Error;
        }
      }
    } else {
      error.Printf("error: invalid number found at offset %" PRIu64,
                   start_index);
      value = std::move(error.GetString());
      return Token::Error;
    }
  } break;
  default:
    break;
  }
  error.Printf("error: failed to parse token at offset %" PRIu64
               " (around character '%c')",
               start_index, ch);
  value = std::move(error.GetString());
  return Token::Error;
}

int JSONParser::GetEscapedChar(bool &was_escaped) {
  was_escaped = false;
  const char ch = GetChar();
  if (ch == '\\') {
    was_escaped = true;
    const char ch2 = GetChar();
    switch (ch2) {
    case '"':
    case '\\':
    case '/':
    default:
      break;

    case 'b':
      return '\b';
    case 'f':
      return '\f';
    case 'n':
      return '\n';
    case 'r':
      return '\r';
    case 't':
      return '\t';
    case 'u': {
      const int hi_byte = DecodeHexU8();
      const int lo_byte = DecodeHexU8();
      if (hi_byte >= 0 && lo_byte >= 0)
        return hi_byte << 8 | lo_byte;
      return -1;
    } break;
    }
    return ch2;
  }
  return ch;
}

JSONValue::SP JSONParser::ParseJSONObject() {
  // The "JSONParser::Token::ObjectStart" token should have already been
  // consumed
  // by the time this function is called
  std::unique_ptr<JSONObject> dict_up(new JSONObject());

  std::string value;
  std::string key;
  while (1) {
    JSONParser::Token token = GetToken(value);

    if (token == JSONParser::Token::String) {
      key.swap(value);
      token = GetToken(value);
      if (token == JSONParser::Token::Colon) {
        JSONValue::SP value_sp = ParseJSONValue();
        if (value_sp)
          dict_up->SetObject(key, value_sp);
        else
          break;
      }
    } else if (token == JSONParser::Token::ObjectEnd) {
      return JSONValue::SP(dict_up.release());
    } else if (token == JSONParser::Token::Comma) {
      continue;
    } else {
      break;
    }
  }
  return JSONValue::SP();
}

JSONValue::SP JSONParser::ParseJSONArray() {
  // The "JSONParser::Token::ObjectStart" token should have already been
  // consumed
  // by the time this function is called
  std::unique_ptr<JSONArray> array_up(new JSONArray());

  std::string value;
  std::string key;
  while (1) {
    JSONValue::SP value_sp = ParseJSONValue();
    if (value_sp)
      array_up->AppendObject(value_sp);
    else
      break;

    JSONParser::Token token = GetToken(value);
    if (token == JSONParser::Token::Comma) {
      continue;
    } else if (token == JSONParser::Token::ArrayEnd) {
      return JSONValue::SP(array_up.release());
    } else {
      break;
    }
  }
  return JSONValue::SP();
}

JSONValue::SP JSONParser::ParseJSONValue() {
  std::string value;
  const JSONParser::Token token = GetToken(value);
  switch (token) {
  case JSONParser::Token::ObjectStart:
    return ParseJSONObject();

  case JSONParser::Token::ArrayStart:
    return ParseJSONArray();

  case JSONParser::Token::Integer: {
    if (value.front() == '-') {
      bool success = false;
      int64_t sval = StringConvert::ToSInt64(value.c_str(), 0, 0, &success);
      if (success)
        return JSONValue::SP(new JSONNumber(sval));
    } else {
      bool success = false;
      uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
      if (success)
        return JSONValue::SP(new JSONNumber(uval));
    }
  } break;

  case JSONParser::Token::Float: {
    bool success = false;
    double val = StringConvert::ToDouble(value.c_str(), 0.0, &success);
    if (success)
      return JSONValue::SP(new JSONNumber(val));
  } break;

  case JSONParser::Token::String:
    return JSONValue::SP(new JSONString(value));

  case JSONParser::Token::True:
    return JSONValue::SP(new JSONTrue());

  case JSONParser::Token::False:
    return JSONValue::SP(new JSONFalse());

  case JSONParser::Token::Null:
    return JSONValue::SP(new JSONNull());

  default:
    break;
  }
  return JSONValue::SP();
}
