//===- MsgPackTypes.h - MsgPack Types ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// This is a data structure for representing MessagePack "documents", with
/// methods to go to and from MessagePack. The types also specialize YAMLIO
/// traits in order to go to and from YAML.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/Optional.h"
#include "llvm/BinaryFormat/MsgPackReader.h"
#include "llvm/BinaryFormat/MsgPackWriter.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/YAMLTraits.h"
#include <vector>

#ifndef LLVM_BINARYFORMAT_MSGPACKTYPES_H
#define LLVM_BINARYFORMAT_MSGPACKTYPES_H

namespace llvm {
namespace msgpack {

class Node;

/// Short-hand for a Node pointer.
using NodePtr = std::shared_ptr<Node>;

/// Short-hand for an Optional Node pointer.
using OptNodePtr = Optional<NodePtr>;

/// Abstract base-class which can be any MessagePack type.
class Node {
public:
  enum NodeKind {
    NK_Scalar,
    NK_Array,
    NK_Map,
  };

private:
  virtual void anchor() = 0;
  const NodeKind Kind;

  static Expected<OptNodePtr> readArray(Reader &MPReader, size_t Length);
  static Expected<OptNodePtr> readMap(Reader &MPReader, size_t Length);

public:
  NodeKind getKind() const { return Kind; }

  /// Construct a Node. Used by derived classes to track kind information.
  Node(NodeKind Kind) : Kind(Kind) {}

  virtual ~Node() = default;

  /// Read from a MessagePack reader \p MPReader, returning an error if one is
  /// encountered, or None if \p MPReader is at the end of stream, or some Node
  /// pointer if some type is read.
  static Expected<OptNodePtr> read(Reader &MPReader);

  /// Write to a MessagePack writer \p MPWriter.
  virtual void write(Writer &MPWriter) = 0;
};

/// A MessagePack scalar.
class ScalarNode : public Node {
public:
  enum ScalarKind {
    SK_Int,
    SK_UInt,
    SK_Nil,
    SK_Boolean,
    SK_Float,
    SK_String,
    SK_Binary,
  };

private:
  void anchor() override;

  void destroy();

  ScalarKind SKind;

  union {
    int64_t IntValue;
    uint64_t UIntValue;
    bool BoolValue;
    double FloatValue;
    std::string StringValue;
  };

public:
  /// Construct an Int ScalarNode.
  ScalarNode(int64_t IntValue);
  /// Construct an Int ScalarNode.
  ScalarNode(int32_t IntValue);
  /// Construct an UInt ScalarNode.
  ScalarNode(uint64_t UIntValue);
  /// Construct an UInt ScalarNode.
  ScalarNode(uint32_t UIntValue);
  /// Construct a Nil ScalarNode.
  ScalarNode();
  /// Construct a Boolean ScalarNode.
  ScalarNode(bool BoolValue);
  /// Construct a Float ScalarNode.
  ScalarNode(double FloatValue);
  /// Construct a String ScalarNode.
  ScalarNode(StringRef StringValue);
  /// Construct a String ScalarNode.
  ScalarNode(const char *StringValue);
  /// Construct a String ScalarNode.
  ScalarNode(std::string &&StringValue);
  /// Construct a Binary ScalarNode.
  ScalarNode(MemoryBufferRef BinaryValue);

  ~ScalarNode();

  ScalarNode &operator=(const ScalarNode &RHS) = delete;
  /// A ScalarNode can only be move assigned.
  ScalarNode &operator=(ScalarNode &&RHS);

  /// Change the kind of this ScalarNode, zero initializing it to the new type.
  void setScalarKind(ScalarKind SKind) {
    switch (SKind) {
    case SK_Int:
      *this = int64_t(0);
      break;
    case SK_UInt:
      *this = uint64_t(0);
      break;
    case SK_Boolean:
      *this = false;
      break;
    case SK_Float:
      *this = 0.0;
      break;
    case SK_String:
      *this = StringRef();
      break;
    case SK_Binary:
      *this = MemoryBufferRef("", "");
      break;
    case SK_Nil:
      *this = ScalarNode();
      break;
    }
  }

  /// Get the current kind of ScalarNode.
  ScalarKind getScalarKind() { return SKind; }

  /// Get the value of an Int scalar.
  ///
  /// \warning Assumes getScalarKind() == SK_Int
  int64_t getInt() {
    assert(SKind == SK_Int);
    return IntValue;
  }

  /// Get the value of a UInt scalar.
  ///
  /// \warning Assumes getScalarKind() == SK_UInt
  uint64_t getUInt() {
    assert(SKind == SK_UInt);
    return UIntValue;
  }

  /// Get the value of an Boolean scalar.
  ///
  /// \warning Assumes getScalarKind() == SK_Boolean
  bool getBool() {
    assert(SKind == SK_Boolean);
    return BoolValue;
  }

  /// Get the value of an Float scalar.
  ///
  /// \warning Assumes getScalarKind() == SK_Float
  double getFloat() {
    assert(SKind == SK_Float);
    return FloatValue;
  }

  /// Get the value of a String scalar.
  ///
  /// \warning Assumes getScalarKind() == SK_String
  StringRef getString() {
    assert(SKind == SK_String);
    return StringValue;
  }

  /// Get the value of a Binary scalar.
  ///
  /// \warning Assumes getScalarKind() == SK_Binary
  StringRef getBinary() {
    assert(SKind == SK_Binary);
    return StringValue;
  }

  static bool classof(const Node *N) { return N->getKind() == NK_Scalar; }

  void write(Writer &MPWriter) override;

  /// Parse a YAML scalar of the current ScalarKind from \p ScalarStr.
  ///
  /// \returns An empty string on success, otherwise an error message.
  StringRef inputYAML(StringRef ScalarStr);

  /// Output a YAML scalar of the current ScalarKind into \p OS.
  void outputYAML(raw_ostream &OS) const;

  /// Determine which YAML quoting type the current value would need when
  /// output.
  yaml::QuotingType mustQuoteYAML(StringRef ScalarStr) const;

  /// Get the YAML tag for the current ScalarKind.
  StringRef getYAMLTag() const;

  /// Flag which affects how the type handles YAML tags when reading and
  /// writing.
  ///
  /// When false, tags are used when reading and writing. When reading, the tag
  /// is used to decide the ScalarKind before parsing. When writing, the tag is
  /// output along with the value.
  ///
  /// When true, tags are ignored when reading and writing. When reading, the
  /// ScalarKind is always assumed to be String. When writing, the tag is not
  /// output.
  bool IgnoreTag = false;

  static const char *IntTag;
  static const char *NilTag;
  static const char *BooleanTag;
  static const char *FloatTag;
  static const char *StringTag;
  static const char *BinaryTag;
};

class ArrayNode : public Node, public std::vector<NodePtr> {
  void anchor() override;

public:
  ArrayNode() : Node(NK_Array) {}
  static bool classof(const Node *N) { return N->getKind() == NK_Array; }

  void write(Writer &MPWriter) override {
    MPWriter.writeArraySize(this->size());
    for (auto &N : *this)
      N->write(MPWriter);
  }
};

class MapNode : public Node, public StringMap<NodePtr> {
  void anchor() override;

public:
  MapNode() : Node(NK_Map) {}
  static bool classof(const Node *N) { return N->getKind() == NK_Map; }

  void write(Writer &MPWriter) override {
    MPWriter.writeMapSize(this->size());
    for (auto &N : *this) {
      MPWriter.write(N.first());
      N.second->write(MPWriter);
    }
  }
};

} // end namespace msgpack

namespace yaml {

template <> struct PolymorphicTraits<msgpack::NodePtr> {
  static NodeKind getKind(const msgpack::NodePtr &N) {
    if (isa<msgpack::ScalarNode>(*N))
      return NodeKind::Scalar;
    if (isa<msgpack::MapNode>(*N))
      return NodeKind::Map;
    if (isa<msgpack::ArrayNode>(*N))
      return NodeKind::Sequence;
    llvm_unreachable("NodeKind not supported");
  }
  static msgpack::ScalarNode &getAsScalar(msgpack::NodePtr &N) {
    if (!N || !isa<msgpack::ScalarNode>(*N))
      N.reset(new msgpack::ScalarNode());
    return *cast<msgpack::ScalarNode>(N.get());
  }
  static msgpack::MapNode &getAsMap(msgpack::NodePtr &N) {
    if (!N || !isa<msgpack::MapNode>(*N))
      N.reset(new msgpack::MapNode());
    return *cast<msgpack::MapNode>(N.get());
  }
  static msgpack::ArrayNode &getAsSequence(msgpack::NodePtr &N) {
    if (!N || !isa<msgpack::ArrayNode>(*N))
      N.reset(new msgpack::ArrayNode());
    return *cast<msgpack::ArrayNode>(N.get());
  }
};

template <> struct TaggedScalarTraits<msgpack::ScalarNode> {
  static void output(const msgpack::ScalarNode &S, void *Ctxt,
                     raw_ostream &ScalarOS, raw_ostream &TagOS) {
    if (!S.IgnoreTag)
      TagOS << S.getYAMLTag();
    S.outputYAML(ScalarOS);
  }

  static StringRef input(StringRef ScalarStr, StringRef Tag, void *Ctxt,
                         msgpack::ScalarNode &S) {
    if (Tag == msgpack::ScalarNode::IntTag) {
      S.setScalarKind(msgpack::ScalarNode::SK_UInt);
      if (S.inputYAML(ScalarStr) == StringRef())
        return StringRef();
      S.setScalarKind(msgpack::ScalarNode::SK_Int);
      return S.inputYAML(ScalarStr);
    }

    if (S.IgnoreTag || Tag == msgpack::ScalarNode::StringTag ||
        Tag == "tag:yaml.org,2002:str")
      S.setScalarKind(msgpack::ScalarNode::SK_String);
    else if (Tag == msgpack::ScalarNode::NilTag)
      S.setScalarKind(msgpack::ScalarNode::SK_Nil);
    else if (Tag == msgpack::ScalarNode::BooleanTag)
      S.setScalarKind(msgpack::ScalarNode::SK_Boolean);
    else if (Tag == msgpack::ScalarNode::FloatTag)
      S.setScalarKind(msgpack::ScalarNode::SK_Float);
    else if (Tag == msgpack::ScalarNode::StringTag)
      S.setScalarKind(msgpack::ScalarNode::SK_String);
    else if (Tag == msgpack::ScalarNode::BinaryTag)
      S.setScalarKind(msgpack::ScalarNode::SK_Binary);
    else
      return "Unsupported messagepack tag";

    return S.inputYAML(ScalarStr);
  }

  static QuotingType mustQuote(const msgpack::ScalarNode &S, StringRef Str) {
    return S.mustQuoteYAML(Str);
  }
};

template <> struct CustomMappingTraits<msgpack::MapNode> {
  static void inputOne(IO &IO, StringRef Key, msgpack::MapNode &M) {
    IO.mapRequired(Key.str().c_str(), M[Key]);
  }
  static void output(IO &IO, msgpack::MapNode &M) {
    for (auto &N : M)
      IO.mapRequired(N.getKey().str().c_str(), N.getValue());
  }
};

template <> struct SequenceTraits<msgpack::ArrayNode> {
  static size_t size(IO &IO, msgpack::ArrayNode &A) { return A.size(); }
  static msgpack::NodePtr &element(IO &IO, msgpack::ArrayNode &A,
                                   size_t Index) {
    if (Index >= A.size())
      A.resize(Index + 1);
    return A[Index];
  }
};

} // end namespace yaml
} // end namespace llvm

#endif //  LLVM_BINARYFORMAT_MSGPACKTYPES_H
