//===-- StreamWriter.h ----------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_READOBJ_STREAMWRITER_H
#define LLVM_READOBJ_STREAMWRITER_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>

using namespace llvm;
using namespace llvm::support;

namespace llvm {

template<typename T>
struct EnumEntry {
  StringRef Name;
  T Value;
};

struct HexNumber {
  // To avoid sign-extension we have to explicitly cast to the appropriate
  // unsigned type. The overloads are here so that every type that is implicitly
  // convertible to an integer (including enums and endian helpers) can be used
  // without requiring type traits or call-site changes.
  HexNumber(int8_t   Value) : Value(static_cast<uint8_t >(Value)) { }
  HexNumber(int16_t  Value) : Value(static_cast<uint16_t>(Value)) { }
  HexNumber(int32_t  Value) : Value(static_cast<uint32_t>(Value)) { }
  HexNumber(int64_t  Value) : Value(static_cast<uint64_t>(Value)) { }
  HexNumber(uint8_t  Value) : Value(Value) { }
  HexNumber(uint16_t Value) : Value(Value) { }
  HexNumber(uint32_t Value) : Value(Value) { }
  HexNumber(uint64_t Value) : Value(Value) { }
  uint64_t Value;
};

raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value);

class StreamWriter {
public:
  StreamWriter(raw_ostream &OS)
    : OS(OS)
    , IndentLevel(0) {
  }

  void flush() {
    OS.flush();
  }

  void indent(int Levels = 1) {
    IndentLevel += Levels;
  }

  void unindent(int Levels = 1) {
    IndentLevel = std::max(0, IndentLevel - Levels);
  }

  void printIndent() {
    for (int i = 0; i < IndentLevel; ++i)
      OS << "  ";
  }

  template<typename T>
  HexNumber hex(T Value) {
    return HexNumber(Value);
  }

  template<typename T, typename TEnum>
  void printEnum(StringRef Label, T Value,
                 ArrayRef<EnumEntry<TEnum> > EnumValues) {
    StringRef Name;
    bool Found = false;
    for (size_t i = 0; i < EnumValues.size(); ++i) {
      if (EnumValues[i].Value == Value) {
        Name = EnumValues[i].Name;
        Found = true;
        break;
      }
    }

    if (Found) {
      startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
    } else {
      startLine() << Label << ": " << hex(Value) << "\n";
    }
  }

  template<typename T, typename TFlag>
  void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag> > Flags,
                  TFlag EnumMask = TFlag(0)) {
    typedef EnumEntry<TFlag> FlagEntry;
    typedef SmallVector<FlagEntry, 10> FlagVector;
    FlagVector SetFlags;

    for (typename ArrayRef<FlagEntry>::const_iterator I = Flags.begin(),
                                                 E = Flags.end(); I != E; ++I) {
      if (I->Value == 0)
        continue;

      bool IsEnum = (I->Value & EnumMask) != 0;
      if ((!IsEnum && (Value & I->Value) == I->Value) ||
          (IsEnum  && (Value & EnumMask) == I->Value)) {
        SetFlags.push_back(*I);
      }
    }

    std::sort(SetFlags.begin(), SetFlags.end(), &flagName<TFlag>);

    startLine() << Label << " [ (" << hex(Value) << ")\n";
    for (typename FlagVector::const_iterator I = SetFlags.begin(),
                                             E = SetFlags.end();
                                             I != E; ++I) {
      startLine() << "  " << I->Name << " (" << hex(I->Value) << ")\n";
    }
    startLine() << "]\n";
  }

  template<typename T>
  void printFlags(StringRef Label, T Value) {
    startLine() << Label << " [ (" << hex(Value) << ")\n";
    uint64_t Flag = 1;
    uint64_t Curr = Value;
    while (Curr > 0) {
      if (Curr & 1)
        startLine() << "  " << hex(Flag) << "\n";
      Curr >>= 1;
      Flag <<= 1;
    }
    startLine() << "]\n";
  }

  void printNumber(StringRef Label, uint64_t Value) {
    startLine() << Label << ": " << Value << "\n";
  }

  void printNumber(StringRef Label, uint32_t Value) {
    startLine() << Label << ": " << Value << "\n";
  }

  void printNumber(StringRef Label, uint16_t Value) {
    startLine() << Label << ": " << Value << "\n";
  }

  void printNumber(StringRef Label, uint8_t Value) {
    startLine() << Label << ": " << unsigned(Value) << "\n";
  }

  void printNumber(StringRef Label, int64_t Value) {
    startLine() << Label << ": " << Value << "\n";
  }

  void printNumber(StringRef Label, int32_t Value) {
    startLine() << Label << ": " << Value << "\n";
  }

  void printNumber(StringRef Label, int16_t Value) {
    startLine() << Label << ": " << Value << "\n";
  }

  void printNumber(StringRef Label, int8_t Value) {
    startLine() << Label << ": " << int(Value) << "\n";
  }

  template<typename T>
  void printHex(StringRef Label, T Value) {
    startLine() << Label << ": " << hex(Value) << "\n";
  }

  template<typename T>
  void printHex(StringRef Label, StringRef Str, T Value) {
    startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
  }

  void printString(StringRef Label, StringRef Value) {
    startLine() << Label << ": " << Value << "\n";
  }

  void printString(StringRef Label, const std::string &Value) {
    startLine() << Label << ": " << Value << "\n";
  }

  template<typename T>
  void printNumber(StringRef Label, StringRef Str, T Value) {
    startLine() << Label << ": " << Str << " (" << Value << ")\n";
  }

  void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
    printBinaryImpl(Label, Str, Value, false);
  }

  void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
    ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
                        Value.size());
    printBinaryImpl(Label, Str, V, false);
  }

  void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
    printBinaryImpl(Label, StringRef(), Value, false);
  }

  void printBinary(StringRef Label, ArrayRef<char> Value) {
    ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
                        Value.size());
    printBinaryImpl(Label, StringRef(), V, false);
  }

  void printBinary(StringRef Label, StringRef Value) {
    ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
                        Value.size());
    printBinaryImpl(Label, StringRef(), V, false);
  }

  void printBinaryBlock(StringRef Label, StringRef Value) {
    ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
                        Value.size());
    printBinaryImpl(Label, StringRef(), V, true);
  }

  raw_ostream& startLine() {
    printIndent();
    return OS;
  }

  raw_ostream& getOStream() {
    return OS;
  }

private:
  template<typename T>
  static bool flagName(const EnumEntry<T>& lhs, const EnumEntry<T>& rhs) {
    return lhs.Name < rhs.Name;
  }

  void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
                       bool Block);

  raw_ostream &OS;
  int IndentLevel;
};

struct DictScope {
  DictScope(StreamWriter& W, StringRef N) : W(W) {
    W.startLine() << N << " {\n";
    W.indent();
  }

  ~DictScope() {
    W.unindent();
    W.startLine() << "}\n";
  }

  StreamWriter& W;
};

struct ListScope {
  ListScope(StreamWriter& W, StringRef N) : W(W) {
    W.startLine() << N << " [\n";
    W.indent();
  }

  ~ListScope() {
    W.unindent();
    W.startLine() << "]\n";
  }

  StreamWriter& W;
};

} // namespace llvm

#endif
