//===--- JSONSerialization.h - JSON serialization support -------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Provides an interface for serializing to JSON.
/// \note This does not include support for deserializing JSON; since JSON is
/// a subset of YAML, use LLVM's YAML parsing support instead.
///
//===----------------------------------------------------------------------===//

#ifndef SWIFT_BASIC_JSONSERIALIZATION_H
#define SWIFT_BASIC_JSONSERIALIZATION_H

#include "swift/Basic/LLVM.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"

#include <map>
#include <vector>

namespace swift {
namespace json {

/// This class should be specialized by any type that needs to be converted
/// to/from a JSON object.  For example:
///
///     struct ObjectTraits<MyStruct> {
///       static void mapping(Output &out, MyStruct &s) {
///         out.mapRequired("name", s.name);
///         out.mapRequired("size", s.size);
///         out.mapOptional("age",  s.age);
///       }
///     };
template<class T>
struct ObjectTraits {
  // Must provide:
  // static void mapping(Output &out, T &fields);
  // Optionally may provide:
  // static StringRef validate(Output &out, T &fields);
};


/// This class should be specialized by any integral type that converts
/// to/from a JSON scalar where there is a one-to-one mapping between
/// in-memory values and a string in JSON.  For example:
///
///     struct ScalarEnumerationTraits<Colors> {
///         static void enumeration(Output &out, Colors &value) {
///           out.enumCase(value, "red",   cRed);
///           out.enumCase(value, "blue",  cBlue);
///           out.enumCase(value, "green", cGreen);
///         }
///       };
template<typename T>
struct ScalarEnumerationTraits {
  // Must provide:
  // static void enumeration(Output &out, T &value);
};


/// This class should be specialized by any integer type that is a union
/// of bit values and the JSON representation is an array of
/// strings.  For example:
///
///      struct ScalarBitSetTraits<MyFlags> {
///        static void bitset(Output &out, MyFlags &value) {
///          out.bitSetCase(value, "big",   flagBig);
///          out.bitSetCase(value, "flat",  flagFlat);
///          out.bitSetCase(value, "round", flagRound);
///        }
///      };
template<typename T>
struct ScalarBitSetTraits {
  // Must provide:
  // static void bitset(Output &out, T &value);
};


/// This class should be specialized by type that requires custom conversion
/// to/from a json scalar.  For example:
///
///    template<>
///    struct ScalarTraits<MyType> {
///      static void output(const MyType &val, llvm::raw_ostream &out) {
///        // stream out custom formatting
///        out << llvm::format("%x", val);
///      }
///      static bool mustQuote(StringRef) { return true; }
///    };
template<typename T>
struct ScalarTraits {
  // Must provide:
  //
  // Function to write the value as a string:
  //static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
  //
  // Function to determine if the value should be quoted.
  //static bool mustQuote(StringRef);
};

/// This is an optimized form of ScalarTraits in case the scalar value is
/// already present in a memory buffer.  For example:
///
///    template<>
///    struct ScalarReferenceTraits<MyType> {
///      static StringRef stringRef(const MyType &val) {
///        // Retrieve scalar value from memory
///        return value.stringValue;
///      }
///      static bool mustQuote(StringRef) { return true; }
///    };
template<typename T>
struct ScalarReferenceTraits {
  // Must provide:
  //
  // Function to return a string representation of the value.
  // static StringRef stringRef(const T &value);
  //
  // Function to determine if the value should be quoted.
  // static bool mustQuote(StringRef);
};

/// This class should be specialized by any type that can be 'null' in JSON.
/// For example:
///
///    template<>
///    struct NullableTraits<MyType *> > {
///      static bool isNull(MyType *&ptr) {
///        return !ptr;
///      }
///      static MyType &get(MyType *&ptr) {
///        return *ptr;
///      }
///    };
template<typename T>
struct NullableTraits {
  // Must provide:
  //
  // Function to return true if the value is 'null'.
  // static bool isNull(const T &Val);
  //
  // Function to return a reference to the unwrapped value.
  // static T::value_type &get(const T &Val);
};


/// This class should be specialized by any type that needs to be converted
/// to/from a JSON array.  For example:
///
///    template<>
///    struct ArrayTraits< std::vector<MyType> > {
///      static size_t size(Output &out, std::vector<MyType> &seq) {
///        return seq.size();
///      }
///      static MyType& element(Output &, std::vector<MyType> &seq, size_t index) {
///        if (index >= seq.size())
///          seq.resize(index+1);
///        return seq[index];
///      }
///    };
template<typename T>
struct ArrayTraits {
  // Must provide:
  // static size_t size(Output &out, T &seq);
  // static T::value_type& element(Output &out, T &seq, size_t index);
};

// Only used by compiler if both template types are the same
template <typename T, T>
struct SameType;

// Only used for better diagnostics of missing traits
template <typename T>
struct MissingTrait;

// Test if ScalarEnumerationTraits<T> is defined on type T.
template <class T>
struct has_ScalarEnumerationTraits
{
  using Signature_enumeration = void (*)(class Output &, T &);

  template <typename U>
  static char test(SameType<Signature_enumeration, &U::enumeration>*);

  template <typename U>
  static double test(...);

public:
  static bool const value =
  (sizeof(test<ScalarEnumerationTraits<T> >(nullptr)) == 1);
};


// Test if ScalarBitSetTraits<T> is defined on type T.
template <class T>
struct has_ScalarBitSetTraits
{
  using Signature_bitset = void (*)(class Output &, T &);

  template <typename U>
  static char test(SameType<Signature_bitset, &U::bitset>*);

  template <typename U>
  static double test(...);

public:
  static bool const value = (sizeof(test<ScalarBitSetTraits<T> >(nullptr)) == 1);
};


// Test if ScalarTraits<T> is defined on type T.
template <class T>
struct has_ScalarTraits
{
  using Signature_output = void (*)(const T &, llvm::raw_ostream &);
  using Signature_mustQuote = bool (*)(StringRef);

  template <typename U>
  static char test(SameType<Signature_output, &U::output> *,
                   SameType<Signature_mustQuote, &U::mustQuote> *);

  template <typename U>
  static double test(...);

public:
  static bool const value =
  (sizeof(test<ScalarTraits<T>>(nullptr, nullptr)) == 1);
};

// Test if ScalarReferenceTraits<T> is defined on type T.
template <class T>
struct has_ScalarReferenceTraits
{
  using Signature_stringRef = StringRef (*)(const T &);
  using Signature_mustQuote = bool (*)(StringRef);

  template <typename U>
  static char test(SameType<Signature_stringRef, &U::stringRef> *,
                   SameType<Signature_mustQuote, &U::mustQuote> *);

  template <typename U>
  static double test(...);

public:
  static bool const value =
  (sizeof(test<ScalarReferenceTraits<T>>(nullptr, nullptr)) == 1);
};

// Test if ObjectTraits<T> is defined on type T.
template <class T>
struct has_ObjectTraits
{
  using Signature_mapping = void (*)(class Output &, T &);

  template <typename U>
  static char test(SameType<Signature_mapping, &U::mapping>*);

  template <typename U>
  static double test(...);

public:
  static bool const value = (sizeof(test<ObjectTraits<T> >(nullptr)) == 1);
};

// Test if ObjectTraits<T>::validate() is defined on type T.
template <class T>
struct has_ObjectValidateTraits
{
  using Signature_validate = StringRef (*)(class Output &, T &);

  template <typename U>
  static char test(SameType<Signature_validate, &U::validate>*);

  template <typename U>
  static double test(...);

public:
  static bool const value = (sizeof(test<ObjectTraits<T> >(nullptr)) == 1);
};



// Test if ArrayTraits<T> is defined on type T.
template <class T>
struct has_ArrayMethodTraits
{
  using Signature_size = size_t (*)(class Output &, T &);

  template <typename U>
  static char test(SameType<Signature_size, &U::size>*);
  
  template <typename U>
  static double test(...);
  
public:
  static bool const value =  (sizeof(test<ArrayTraits<T> >(nullptr)) == 1);
};

// Test if ArrayTraits<T> is defined on type T
template<typename T>
struct has_ArrayTraits : public std::integral_constant<bool,
    has_ArrayMethodTraits<T>::value > { };

// Test if NullableTraits<T> is defined on type T.
template <class T>
struct has_NullableTraits
{
  using Signature_isNull = bool (*)(T &);

  template <typename U>
  static char test(SameType<Signature_isNull, &U::isNull> *);

  template <typename U>
  static double test(...);

public:
  static bool const value =
  (sizeof(test<NullableTraits<T>>(nullptr)) == 1);
};

inline bool isNumber(StringRef S) {
  static const char DecChars[] = "0123456789";
  if (S.find_first_not_of(DecChars) == StringRef::npos)
    return true;

  llvm::Regex FloatMatcher(
      "^(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$");
  if (FloatMatcher.match(S))
    return true;

  return false;
}

inline bool isNumeric(StringRef S) {
  if ((S.front() == '-' || S.front() == '+') && isNumber(S.drop_front()))
    return true;

  if (isNumber(S))
    return true;

  return false;
}

inline bool isNull(StringRef S) {
  return S.equals("null");
}

inline bool isBool(StringRef S) {
  return S.equals("true") || S.equals("false");
}

template<typename T>
struct missingTraits : public std::integral_constant<bool,
    !has_ScalarEnumerationTraits<T>::value
 && !has_ScalarBitSetTraits<T>::value
 && !has_ScalarTraits<T>::value
 && !has_ScalarReferenceTraits<T>::value
 && !has_NullableTraits<T>::value
 && !has_ObjectTraits<T>::value
 && !has_ArrayTraits<T>::value> {};

template<typename T>
struct validatedObjectTraits : public std::integral_constant<bool,
    has_ObjectTraits<T>::value
 && has_ObjectValidateTraits<T>::value> {};

template<typename T>
struct unvalidatedObjectTraits : public std::integral_constant<bool,
    has_ObjectTraits<T>::value
&& !has_ObjectValidateTraits<T>::value> {};

class Output {
public:
  using UserInfoMap = std::map<void *, void *>;

private:
  enum State {
    ArrayFirstValue,
    ArrayOtherValue,
    ObjectFirstKey,
    ObjectOtherKey
  };

  llvm::raw_ostream &Stream;
  SmallVector<State, 8> StateStack;
  bool PrettyPrint;
  bool NeedBitValueComma;
  bool EnumerationMatchFound;
  UserInfoMap UserInfo;

public:
  Output(llvm::raw_ostream &os, UserInfoMap UserInfo = {},
         bool PrettyPrint = true)
      : Stream(os), PrettyPrint(PrettyPrint), NeedBitValueComma(false),
        EnumerationMatchFound(false), UserInfo(UserInfo) {}
  virtual ~Output() = default;

  UserInfoMap &getUserInfo() {
    return UserInfo;
  }

  unsigned beginArray();
  bool preflightElement(unsigned, void *&);
  void postflightElement(void*);
  void endArray();
  bool canElideEmptyArray();

  void beginObject();
  void endObject();
  bool preflightKey(StringRef, bool, bool, bool &, void *&);
  void postflightKey(void*);

  void beginEnumScalar();
  bool matchEnumScalar(const char*, bool);
  void endEnumScalar();

  bool beginBitSetScalar(bool &);
  bool bitSetMatch(const char*, bool);
  void endBitSetScalar();

  void scalarString(StringRef &, bool);
  void null();

  template <typename T>
  void enumCase(T &Val, const char* Str, const T ConstVal) {
    if (matchEnumScalar(Str, Val == ConstVal)) {
      Val = ConstVal;
    }
  }

  template <typename T>
  void bitSetCase(T &Val, const char* Str, const T ConstVal) {
    if (bitSetMatch(Str, (Val & ConstVal) == ConstVal)) {
      Val = Val | ConstVal;
    }
  }

  template <typename T>
  void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
    if (bitSetMatch(Str, (Val & Mask) == ConstVal))
      Val = Val | ConstVal;
  }

  template <typename T>
  void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
                        uint32_t Mask) {
    if (bitSetMatch(Str, (Val & Mask) == ConstVal))
      Val = Val | ConstVal;
  }

  template <typename T>
  void mapRequired(StringRef Key, T& Val) {
    this->processKey(Key, Val, true);
  }

  template <typename T>
  typename std::enable_if<has_ArrayTraits<T>::value,void>::type
  mapOptional(StringRef Key, T& Val) {
    // omit key/value instead of outputting empty array
    if (this->canElideEmptyArray() && !(Val.begin() != Val.end()))
      return;
    this->processKey(Key, Val, false);
  }

  template <typename T>
  void mapOptional(StringRef Key, Optional<T> &Val) {
    processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false);
  }

  template <typename T>
  typename std::enable_if<!has_ArrayTraits<T>::value,void>::type
  mapOptional(StringRef Key, T& Val) {
    this->processKey(Key, Val, false);
  }

  template <typename T>
  void mapOptional(StringRef Key, T& Val, const T& Default) {
    this->processKeyWithDefault(Key, Val, Default, false);
  }

private:
  template <typename T>
  void processKeyWithDefault(StringRef Key, Optional<T> &Val,
                             const Optional<T> &DefaultValue, bool Required) {
    assert(!DefaultValue.hasValue() &&
           "Optional<T> shouldn't have a value!");
    void *SaveInfo;
    bool UseDefault;
    const bool sameAsDefault = !Val.hasValue();
    if (!Val.hasValue())
      Val = T();
    if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
                           SaveInfo)) {
      jsonize(*this, Val.getValue(), Required);
      this->postflightKey(SaveInfo);
    } else {
      if (UseDefault)
        Val = DefaultValue;
    }
  }

  template <typename T>
  void processKeyWithDefault(StringRef Key, T &Val, const T &DefaultValue,
                             bool Required) {
    void *SaveInfo;
    bool UseDefault;
    const bool sameAsDefault = Val == DefaultValue;
    if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
                           SaveInfo)) {
      jsonize(*this, Val, Required);
      this->postflightKey(SaveInfo);
    } else {
      if (UseDefault)
        Val = DefaultValue;
    }
  }

  template <typename T>
  void processKey(StringRef Key, T &Val, bool Required) {
    void *SaveInfo;
    bool UseDefault;
    if (this->preflightKey(Key, Required, false, UseDefault, SaveInfo)) {
      jsonize(*this, Val, Required);
      this->postflightKey(SaveInfo);
    }
  }

private:
  void indent();
};

template <typename T> struct ArrayTraits<std::vector<T>> {
  static size_t size(Output &out, std::vector<T> &seq) { return seq.size(); }

  static T &element(Output &out, std::vector<T> &seq, size_t index) {
    if (index >= seq.size())
      seq.resize(index + 1);
    return seq[index];
  }
};

template<>
struct ScalarReferenceTraits<bool> {
  static StringRef stringRef(const bool &);
  static bool mustQuote(StringRef) { return false; }
};

template<>
struct ScalarReferenceTraits<StringRef> {
  static StringRef stringRef(const StringRef &);
  static bool mustQuote(StringRef S) { return true; }
};

template<>
struct ScalarReferenceTraits<std::string> {
  static StringRef stringRef(const std::string &);
  static bool mustQuote(StringRef S) { return true; }
};

template<>
struct ScalarTraits<uint8_t> {
  static void output(const uint8_t &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

template<>
struct ScalarTraits<uint16_t> {
  static void output(const uint16_t &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

template<>
struct ScalarTraits<uint32_t> {
  static void output(const uint32_t &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

#if defined(_MSC_VER)
// In MSVC, 'unsigned long' is 32bit size and different from uint32_t,
// and it is used to define swift::sys::ProcessId.
template<>
struct ScalarTraits<unsigned long> {
  static void output(const unsigned long &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};
#endif

template<>
struct ScalarTraits<uint64_t> {
  static void output(const uint64_t &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

template<>
struct ScalarTraits<int8_t> {
  static void output(const int8_t &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

template<>
struct ScalarTraits<int16_t> {
  static void output(const int16_t &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

template<>
struct ScalarTraits<int32_t> {
  static void output(const int32_t &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

template<>
struct ScalarTraits<int64_t> {
  static void output(const int64_t &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

template<>
struct ScalarTraits<float> {
  static void output(const float &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

template<>
struct ScalarTraits<double> {
  static void output(const double &, llvm::raw_ostream &);
  static bool mustQuote(StringRef) { return false; }
};

template<typename T>
typename std::enable_if<has_ScalarEnumerationTraits<T>::value,void>::type
jsonize(Output &out, T &Val, bool) {
  out.beginEnumScalar();
  ScalarEnumerationTraits<T>::enumeration(out, Val);
  out.endEnumScalar();
}

template<typename T>
typename std::enable_if<has_ScalarBitSetTraits<T>::value,void>::type
jsonize(Output &out, T &Val, bool) {
  bool DoClear;
  if (out.beginBitSetScalar(DoClear)) {
    if (DoClear)
      Val = static_cast<T>(0);
    ScalarBitSetTraits<T>::bitset(out, Val);
    out.endBitSetScalar();
  }
}


template<typename T>
typename std::enable_if<has_ScalarTraits<T>::value,void>::type
jsonize(Output &out, T &Val, bool) {
  {
    SmallString<64> Storage;
    llvm::raw_svector_ostream Buffer(Storage);
    Buffer.SetUnbuffered();
    ScalarTraits<T>::output(Val, Buffer);
    StringRef Str = Buffer.str();
    out.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
  }
}

template <typename T>
typename std::enable_if<has_ScalarReferenceTraits<T>::value, void>::type
jsonize(Output &out, T &Val, bool) {
  StringRef Str = ScalarReferenceTraits<T>::stringRef(Val);
  out.scalarString(Str, ScalarReferenceTraits<T>::mustQuote(Str));
}

template<typename T>
typename std::enable_if<has_NullableTraits<T>::value,void>::type
jsonize(Output &out, T &Obj, bool) {
  if (NullableTraits<T>::isNull(Obj))
    out.null();
  else
    jsonize(out, NullableTraits<T>::get(Obj), true);
}


template<typename T>
typename std::enable_if<validatedObjectTraits<T>::value, void>::type
jsonize(Output &out, T &Val, bool) {
  out.beginObject();
  {
    StringRef Err = ObjectTraits<T>::validate(out, Val);
    if (!Err.empty()) {
      llvm::errs() << Err << "\n";
      assert(Err.empty() && "invalid struct trying to be written as json");
    }
  }
  ObjectTraits<T>::mapping(out, Val);
  out.endObject();
}

template<typename T>
typename std::enable_if<unvalidatedObjectTraits<T>::value, void>::type
jsonize(Output &out, T &Val, bool) {
  out.beginObject();
  ObjectTraits<T>::mapping(out, Val);
  out.endObject();
}

template<typename T>
typename std::enable_if<missingTraits<T>::value, void>::type
jsonize(Output &out, T &Val, bool) {
  char missing_json_trait_for_type[sizeof(MissingTrait<T>)];
}

template<typename T>
typename std::enable_if<has_ArrayTraits<T>::value,void>::type
jsonize(Output &out, T &Seq, bool) {
  {
    out.beginArray();
    unsigned count = ArrayTraits<T>::size(out, Seq);
    for (unsigned i=0; i < count; ++i) {
      void *SaveInfo;
      if (out.preflightElement(i, SaveInfo)) {
        jsonize(out, ArrayTraits<T>::element(out, Seq, i), true);
        out.postflightElement(SaveInfo);
      }
    }
    out.endArray();
  }
}

// Define non-member operator<< so that Output can stream out a map.
template <typename T>
inline
typename
std::enable_if<swift::json::has_ObjectTraits<T>::value, Output &>::type
operator<<(Output &yout, T &map) {
  jsonize(yout, map, true);
  return yout;
}

// Define non-member operator<< so that Output can stream out an array.
template <typename T>
inline
typename
std::enable_if<swift::json::has_ArrayTraits<T>::value, Output &>::type
operator<<(Output &yout, T &seq) {
  jsonize(yout, seq, true);
  return yout;
}

} // end namespace json
} // end namespace swift

#endif // SWIFT_BASIC_JSONSERIALIZATION_H
