/*
 * Copyright 2017 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FLATBUFFERS_MINIREFLECT_H_
#define FLATBUFFERS_MINIREFLECT_H_

#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/util.h"

namespace flatbuffers {

// Utilities that can be used with the "mini reflection" tables present
// in generated code with --reflect-types (only types) or --reflect-names
// (also names).
// This allows basic reflection functionality such as pretty-printing
// that does not require the use of the schema parser or loading of binary
// schema files at runtime (reflection.h).

// For any of the functions below that take `const TypeTable *`, you pass
// `FooTypeTable()` if the type of the root is `Foo`.

// First, a generic iterator that can be used by multiple algorithms.

struct IterationVisitor {
  // These mark the scope of a table or struct.
  virtual void StartSequence() {}
  virtual void EndSequence() {}
  // Called for each field regardless of whether it is present or not.
  // If not present, val == nullptr. set_idx is the index of all set fields.
  virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/,
                     ElementaryType /*type*/, bool /*is_vector*/,
                     const TypeTable * /*type_table*/, const char * /*name*/,
                     const uint8_t * /*val*/) {}
  // Called for a value that is actually present, after a field, or as part
  // of a vector.
  virtual void UType(uint8_t, const char *) {}
  virtual void Bool(bool) {}
  virtual void Char(int8_t, const char *) {}
  virtual void UChar(uint8_t, const char *) {}
  virtual void Short(int16_t, const char *) {}
  virtual void UShort(uint16_t, const char *) {}
  virtual void Int(int32_t, const char *) {}
  virtual void UInt(uint32_t, const char *) {}
  virtual void Long(int64_t) {}
  virtual void ULong(uint64_t) {}
  virtual void Float(float) {}
  virtual void Double(double) {}
  virtual void String(const String *) {}
  virtual void Unknown(const uint8_t *) {}  // From a future version.
  // These mark the scope of a vector.
  virtual void StartVector() {}
  virtual void EndVector() {}
  virtual void Element(size_t /*i*/, ElementaryType /*type*/,
                       const TypeTable * /*type_table*/,
                       const uint8_t * /*val*/) {}
  virtual ~IterationVisitor() {}
};

inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
  switch (type) {
    case ET_UTYPE:
    case ET_BOOL:
    case ET_CHAR:
    case ET_UCHAR: return 1;
    case ET_SHORT:
    case ET_USHORT: return 2;
    case ET_INT:
    case ET_UINT:
    case ET_FLOAT:
    case ET_STRING: return 4;
    case ET_LONG:
    case ET_ULONG:
    case ET_DOUBLE: return 8;
    case ET_SEQUENCE:
      switch (type_table->st) {
        case ST_TABLE:
        case ST_UNION: return 4;
        case ST_STRUCT:
          return static_cast<size_t>(type_table->values[type_table->num_elems]);
        default: FLATBUFFERS_ASSERT(false); return 1;
      }
    default: FLATBUFFERS_ASSERT(false); return 1;
  }
}

inline int64_t LookupEnum(int64_t enum_val, const int64_t *values,
                          size_t num_values) {
  if (!values) return enum_val;
  for (size_t i = 0; i < num_values; i++) {
    if (enum_val == values[i]) return static_cast<int64_t>(i);
  }
  return -1;  // Unknown enum value.
}

template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
  if (!type_table || !type_table->names) return nullptr;
  auto i = LookupEnum(static_cast<int64_t>(tval), type_table->values,
                      type_table->num_elems);
  if (i >= 0 && i < static_cast<int64_t>(type_table->num_elems)) {
    return type_table->names[i];
  }
  return nullptr;
}

void IterateObject(const uint8_t *obj, const TypeTable *type_table,
                   IterationVisitor *visitor);

inline void IterateValue(ElementaryType type, const uint8_t *val,
                         const TypeTable *type_table, const uint8_t *prev_val,
                         soffset_t vector_index, IterationVisitor *visitor) {
  switch (type) {
    case ET_UTYPE: {
      auto tval = ReadScalar<uint8_t>(val);
      visitor->UType(tval, EnumName(tval, type_table));
      break;
    }
    case ET_BOOL: {
      visitor->Bool(ReadScalar<uint8_t>(val) != 0);
      break;
    }
    case ET_CHAR: {
      auto tval = ReadScalar<int8_t>(val);
      visitor->Char(tval, EnumName(tval, type_table));
      break;
    }
    case ET_UCHAR: {
      auto tval = ReadScalar<uint8_t>(val);
      visitor->UChar(tval, EnumName(tval, type_table));
      break;
    }
    case ET_SHORT: {
      auto tval = ReadScalar<int16_t>(val);
      visitor->Short(tval, EnumName(tval, type_table));
      break;
    }
    case ET_USHORT: {
      auto tval = ReadScalar<uint16_t>(val);
      visitor->UShort(tval, EnumName(tval, type_table));
      break;
    }
    case ET_INT: {
      auto tval = ReadScalar<int32_t>(val);
      visitor->Int(tval, EnumName(tval, type_table));
      break;
    }
    case ET_UINT: {
      auto tval = ReadScalar<uint32_t>(val);
      visitor->UInt(tval, EnumName(tval, type_table));
      break;
    }
    case ET_LONG: {
      visitor->Long(ReadScalar<int64_t>(val));
      break;
    }
    case ET_ULONG: {
      visitor->ULong(ReadScalar<uint64_t>(val));
      break;
    }
    case ET_FLOAT: {
      visitor->Float(ReadScalar<float>(val));
      break;
    }
    case ET_DOUBLE: {
      visitor->Double(ReadScalar<double>(val));
      break;
    }
    case ET_STRING: {
      val += ReadScalar<uoffset_t>(val);
      visitor->String(reinterpret_cast<const String *>(val));
      break;
    }
    case ET_SEQUENCE: {
      switch (type_table->st) {
        case ST_TABLE:
          val += ReadScalar<uoffset_t>(val);
          IterateObject(val, type_table, visitor);
          break;
        case ST_STRUCT: IterateObject(val, type_table, visitor); break;
        case ST_UNION: {
          val += ReadScalar<uoffset_t>(val);
          FLATBUFFERS_ASSERT(prev_val);
          auto union_type = *prev_val;  // Always a uint8_t.
          if (vector_index >= 0) {
            auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val);
            union_type = type_vec->Get(static_cast<uoffset_t>(vector_index));
          }
          auto type_code_idx =
              LookupEnum(union_type, type_table->values, type_table->num_elems);
          if (type_code_idx >= 0 &&
              type_code_idx < static_cast<int32_t>(type_table->num_elems)) {
            auto type_code = type_table->type_codes[type_code_idx];
            switch (type_code.base_type) {
              case ET_SEQUENCE: {
                auto ref = type_table->type_refs[type_code.sequence_ref]();
                IterateObject(val, ref, visitor);
                break;
              }
              case ET_STRING:
                visitor->String(reinterpret_cast<const String *>(val));
                break;
              default: visitor->Unknown(val);
            }
          } else {
            visitor->Unknown(val);
          }
          break;
        }
        case ST_ENUM: FLATBUFFERS_ASSERT(false); break;
      }
      break;
    }
    default: {
      visitor->Unknown(val);
      break;
    }
  }
}

inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
                          IterationVisitor *visitor) {
  visitor->StartSequence();
  const uint8_t *prev_val = nullptr;
  size_t set_idx = 0;
  size_t array_idx = 0;
  for (size_t i = 0; i < type_table->num_elems; i++) {
    auto type_code = type_table->type_codes[i];
    auto type = static_cast<ElementaryType>(type_code.base_type);
    auto is_repeating = type_code.is_repeating != 0;
    auto ref_idx = type_code.sequence_ref;
    const TypeTable *ref = nullptr;
    if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); }
    auto name = type_table->names ? type_table->names[i] : nullptr;
    const uint8_t *val = nullptr;
    if (type_table->st == ST_TABLE) {
      val = reinterpret_cast<const Table *>(obj)->GetAddressOf(
          FieldIndexToOffset(static_cast<voffset_t>(i)));
    } else {
      val = obj + type_table->values[i];
    }
    visitor->Field(i, set_idx, type, is_repeating, ref, name, val);
    if (val) {
      set_idx++;
      if (is_repeating) {
        auto elem_ptr = val;
        size_t size = 0;
        if (type_table->st == ST_TABLE) {
          // variable length vector
          val += ReadScalar<uoffset_t>(val);
          auto vec = reinterpret_cast<const Vector<uint8_t> *>(val);
          elem_ptr = vec->Data();
          size = vec->size();
        } else {
          // otherwise fixed size array
          size = type_table->array_sizes[array_idx];
          ++array_idx;
        }
        visitor->StartVector();
        for (size_t j = 0; j < size; j++) {
          visitor->Element(j, type, ref, elem_ptr);
          IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j),
                       visitor);
          elem_ptr += InlineSize(type, ref);
        }
        visitor->EndVector();
      } else {
        IterateValue(type, val, ref, prev_val, -1, visitor);
      }
    }
    prev_val = val;
  }
  visitor->EndSequence();
}

inline void IterateFlatBuffer(const uint8_t *buffer,
                              const TypeTable *type_table,
                              IterationVisitor *callback) {
  IterateObject(GetRoot<uint8_t>(buffer), type_table, callback);
}

// Outputting a Flatbuffer to a string. Tries to conform as close to JSON /
// the output generated by idl_gen_text.cpp.

struct ToStringVisitor : public IterationVisitor {
  std::string s;
  std::string d;
  bool q;
  std::string in;
  size_t indent_level;
  bool vector_delimited;
  ToStringVisitor(std::string delimiter, bool quotes, std::string indent,
                  bool vdelimited = true)
      : d(delimiter),
        q(quotes),
        in(indent),
        indent_level(0),
        vector_delimited(vdelimited) {}
  ToStringVisitor(std::string delimiter)
      : d(delimiter),
        q(false),
        in(""),
        indent_level(0),
        vector_delimited(true) {}

  void append_indent() {
    for (size_t i = 0; i < indent_level; i++) { s += in; }
  }

  void StartSequence() {
    s += "{";
    s += d;
    indent_level++;
  }
  void EndSequence() {
    s += d;
    indent_level--;
    append_indent();
    s += "}";
  }
  void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/,
             bool /*is_vector*/, const TypeTable * /*type_table*/,
             const char *name, const uint8_t *val) {
    if (!val) return;
    if (set_idx) {
      s += ",";
      s += d;
    }
    append_indent();
    if (name) {
      if (q) s += "\"";
      s += name;
      if (q) s += "\"";
      s += ": ";
    }
  }
  template<typename T> void Named(T x, const char *name) {
    if (name) {
      if (q) s += "\"";
      s += name;
      if (q) s += "\"";
    } else {
      s += NumToString(x);
    }
  }
  void UType(uint8_t x, const char *name) { Named(x, name); }
  void Bool(bool x) { s += x ? "true" : "false"; }
  void Char(int8_t x, const char *name) { Named(x, name); }
  void UChar(uint8_t x, const char *name) { Named(x, name); }
  void Short(int16_t x, const char *name) { Named(x, name); }
  void UShort(uint16_t x, const char *name) { Named(x, name); }
  void Int(int32_t x, const char *name) { Named(x, name); }
  void UInt(uint32_t x, const char *name) { Named(x, name); }
  void Long(int64_t x) { s += NumToString(x); }
  void ULong(uint64_t x) { s += NumToString(x); }
  void Float(float x) { s += NumToString(x); }
  void Double(double x) { s += NumToString(x); }
  void String(const struct String *str) {
    EscapeString(str->c_str(), str->size(), &s, true, false);
  }
  void Unknown(const uint8_t *) { s += "(?)"; }
  void StartVector() {
    s += "[";
    if (vector_delimited) {
      s += d;
      indent_level++;
      append_indent();
    } else {
      s += " ";
    }
  }
  void EndVector() {
    if (vector_delimited) {
      s += d;
      indent_level--;
      append_indent();
    } else {
      s += " ";
    }
    s += "]";
  }
  void Element(size_t i, ElementaryType /*type*/,
               const TypeTable * /*type_table*/, const uint8_t * /*val*/) {
    if (i) {
      s += ",";
      if (vector_delimited) {
        s += d;
        append_indent();
      } else {
        s += " ";
      }
    }
  }
};

inline std::string FlatBufferToString(const uint8_t *buffer,
                                      const TypeTable *type_table,
                                      bool multi_line = false,
                                      bool vector_delimited = true) {
  ToStringVisitor tostring_visitor(multi_line ? "\n" : " ", false, "",
                                   vector_delimited);
  IterateFlatBuffer(buffer, type_table, &tostring_visitor);
  return tostring_visitor.s;
}

}  // namespace flatbuffers

#endif  // FLATBUFFERS_MINIREFLECT_H_
