//===---------------------JSON.h --------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H
#define LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H

#include "StdStringExtractor.h"

// C includes
#include <cinttypes>
#include <cstdint>

// C++ includes
#include <map>
#include <memory>
#include <ostream>
#include <string>
#include <vector>

class JSONValue {
public:
  virtual void Write(std::ostream &s) = 0;

  typedef std::shared_ptr<JSONValue> SP;

  enum class Kind { String, Number, True, False, Null, Object, Array };

  JSONValue(Kind k) : m_kind(k) {}

  Kind GetKind() const { return m_kind; }

  virtual ~JSONValue() = default;

private:
  const Kind m_kind;
};

class JSONString : public JSONValue {
public:
  JSONString();
  JSONString(const char *s);
  JSONString(const std::string &s);

  JSONString(const JSONString &s) = delete;
  JSONString &operator=(const JSONString &s) = delete;

  void Write(std::ostream &s) override;

  typedef std::shared_ptr<JSONString> SP;

  std::string GetData() { return m_data; }

  static bool classof(const JSONValue *V) {
    return V->GetKind() == JSONValue::Kind::String;
  }

  ~JSONString() override = default;

private:
  static std::string json_string_quote_metachars(const std::string &);

  std::string m_data;
};

class JSONNumber : public JSONValue {
public:
  typedef std::shared_ptr<JSONNumber> SP;

  // We cretae a constructor for all integer and floating point type with using
  // templates and
  // SFINAE to avoid having ambiguous overloads because of the implicit type
  // promotion. If we
  // would have constructors only with int64_t, uint64_t and double types then
  // constructing a
  // JSONNumber from an int32_t (or any other similar type) would fail to
  // compile.

  template <typename T, typename std::enable_if<
                            std::is_integral<T>::value &&
                            std::is_unsigned<T>::value>::type * = nullptr>
  explicit JSONNumber(T u)
      : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) {
    m_data.m_unsigned = u;
  }

  template <typename T,
            typename std::enable_if<std::is_integral<T>::value &&
                                    std::is_signed<T>::value>::type * = nullptr>
  explicit JSONNumber(T s)
      : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) {
    m_data.m_signed = s;
  }

  template <typename T, typename std::enable_if<
                            std::is_floating_point<T>::value>::type * = nullptr>
  explicit JSONNumber(T d)
      : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) {
    m_data.m_double = d;
  }

  ~JSONNumber() override = default;

  JSONNumber(const JSONNumber &s) = delete;
  JSONNumber &operator=(const JSONNumber &s) = delete;

  void Write(std::ostream &s) override;

  uint64_t GetAsUnsigned() const;

  int64_t GetAsSigned() const;

  double GetAsDouble() const;

  static bool classof(const JSONValue *V) {
    return V->GetKind() == JSONValue::Kind::Number;
  }

private:
  enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type;

  union {
    uint64_t m_unsigned;
    int64_t m_signed;
    double m_double;
  } m_data;
};

class JSONTrue : public JSONValue {
public:
  JSONTrue();

  JSONTrue(const JSONTrue &s) = delete;
  JSONTrue &operator=(const JSONTrue &s) = delete;

  void Write(std::ostream &s) override;

  typedef std::shared_ptr<JSONTrue> SP;

  static bool classof(const JSONValue *V) {
    return V->GetKind() == JSONValue::Kind::True;
  }

  ~JSONTrue() override = default;
};

class JSONFalse : public JSONValue {
public:
  JSONFalse();

  JSONFalse(const JSONFalse &s) = delete;
  JSONFalse &operator=(const JSONFalse &s) = delete;

  void Write(std::ostream &s) override;

  typedef std::shared_ptr<JSONFalse> SP;

  static bool classof(const JSONValue *V) {
    return V->GetKind() == JSONValue::Kind::False;
  }

  ~JSONFalse() override = default;
};

class JSONNull : public JSONValue {
public:
  JSONNull();

  JSONNull(const JSONNull &s) = delete;
  JSONNull &operator=(const JSONNull &s) = delete;

  void Write(std::ostream &s) override;

  typedef std::shared_ptr<JSONNull> SP;

  static bool classof(const JSONValue *V) {
    return V->GetKind() == JSONValue::Kind::Null;
  }

  ~JSONNull() override = default;
};

class JSONObject : public JSONValue {
public:
  JSONObject();

  JSONObject(const JSONObject &s) = delete;
  JSONObject &operator=(const JSONObject &s) = delete;

  void Write(std::ostream &s) override;

  typedef std::shared_ptr<JSONObject> SP;

  static bool classof(const JSONValue *V) {
    return V->GetKind() == JSONValue::Kind::Object;
  }

  bool SetObject(const std::string &key, JSONValue::SP value);

  JSONValue::SP GetObject(const std::string &key) const;

  /// Return keyed value as bool
  ///
  /// \param[in] key
  ///     The value of the key to lookup
  ///
  /// \param[out] value
  ///     The value of the key as a bool.  Undefined if the key doesn't
  ///     exist or if the key is not either true or false.
  ///
  /// \return
  ///     true if the key existed as was a bool value; false otherwise.
  ///     Note the return value is *not* the value of the bool, use
  ///     \b value for that.
  bool GetObjectAsBool(const std::string &key, bool &value) const;

  bool GetObjectAsString(const std::string &key, std::string &value) const;

  ~JSONObject() override = default;

private:
  typedef std::map<std::string, JSONValue::SP> Map;
  typedef Map::iterator Iterator;
  Map m_elements;
};

class JSONArray : public JSONValue {
public:
  JSONArray();

  JSONArray(const JSONArray &s) = delete;
  JSONArray &operator=(const JSONArray &s) = delete;

  void Write(std::ostream &s) override;

  typedef std::shared_ptr<JSONArray> SP;

  static bool classof(const JSONValue *V) {
    return V->GetKind() == JSONValue::Kind::Array;
  }

private:
  typedef std::vector<JSONValue::SP> Vector;
  typedef Vector::iterator Iterator;
  typedef Vector::size_type Index;
  typedef Vector::size_type Size;

public:
  bool SetObject(Index i, JSONValue::SP value);

  bool AppendObject(JSONValue::SP value);

  JSONValue::SP GetObject(Index i);

  Size GetNumElements();

  ~JSONArray() override = default;

  Vector m_elements;
};

class JSONParser : public StdStringExtractor {
public:
  enum Token {
    Invalid,
    Status,
    ObjectStart,
    ObjectEnd,
    ArrayStart,
    ArrayEnd,
    Comma,
    Colon,
    String,
    Integer,
    Float,
    True,
    False,
    Null,
    EndOfFile
  };

  JSONParser(const char *cstr);

  int GetEscapedChar(bool &was_escaped);

  Token GetToken(std::string &value);

  JSONValue::SP ParseJSONValue();

protected:
  JSONValue::SP ParseJSONValue(const std::string &value, const Token &token);

  JSONValue::SP ParseJSONObject();

  JSONValue::SP ParseJSONArray();
};

#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H
