#ifndef AOS_JSON_TO_FLATBUFFER_H_
#define AOS_JSON_TO_FLATBUFFER_H_

#include <cstddef>
#include <fstream>
#include <string>
#include <string_view>

#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/reflection.h"

#include "aos/fast_string_builder.h"
#include "aos/flatbuffer_utils.h"
#include "aos/flatbuffers.h"
#include "aos/flatbuffers/builder.h"
#include "aos/util/file.h"

namespace aos {

// Parses the flatbuffer into the buffer, or returns an empty buffer.
flatbuffers::DetachedBuffer JsonToFlatbuffer(std::string_view data,
                                             FlatbufferType type);

// Parses the flatbuffer into the builder, and returns the offset.
flatbuffers::Offset<flatbuffers::Table> JsonToFlatbuffer(
    std::string_view data, FlatbufferType type,
    flatbuffers::FlatBufferBuilder *fbb);

// Typed versions of the above methods.
template <typename T>
inline flatbuffers::DetachedBuffer JsonToFlatbuffer(
    const std::string_view data) {
  return JsonToFlatbuffer(data, FlatbufferType(T::MiniReflectTypeTable()));
}
template <typename T>
inline flatbuffers::Offset<T> JsonToFlatbuffer(
    const std::string_view data, flatbuffers::FlatBufferBuilder *fbb) {
  return flatbuffers::Offset<T>(
      JsonToFlatbuffer(data, FlatbufferType(T::MiniReflectTypeTable()), fbb).o);
}

template <typename T>
inline fbs::Builder<T> JsonToStaticFlatbuffer(const std::string_view data) {
  const aos::FlatbufferDetachedBuffer<typename T::Flatbuffer> fbs =
      JsonToFlatbuffer<typename T::Flatbuffer>(data);
  fbs::Builder<T> builder(std::make_unique<aos::fbs::AlignedVectorAllocator>());
  CHECK(builder.get()->FromFlatbuffer(&fbs.message()));
  return builder;
}

struct JsonOptions {
  // controls if the Json is written out on multiple lines or one.
  bool multi_line = false;
  // the contents of vectors longer than max_vector_size will be skipped.
  size_t max_vector_size = SIZE_MAX;
  // more extensive version of multi_line that prints every single field on its
  // own line.
  bool max_multi_line = false;
  // Will integers be printed in hexadecimal form instead of decimal.
  bool use_hex = false;
};

// Converts a flatbuffer into a Json string.
// The methods below are generally more useful than TableFlatbufferToJson.
::std::string TableFlatbufferToJson(const flatbuffers::Table *t,
                                    const flatbuffers::TypeTable *typetable,
                                    JsonOptions json_options = {});

// Converts a Flatbuffer<T> holding a flatbuffer to JSON.
template <typename T>
inline ::std::string FlatbufferToJson(const Flatbuffer<T> &flatbuffer,
                                      JsonOptions json_options = {}) {
  return TableFlatbufferToJson(
      reinterpret_cast<const flatbuffers::Table *>(&flatbuffer.message()),
      Flatbuffer<T>::MiniReflectTypeTable(), json_options);
}

template <typename T, typename Enable = T::Flatbuffer>
inline ::std::string FlatbufferToJson(const fbs::Builder<T> &flatbuffer,
                                      JsonOptions json_options = {}) {
  return FlatbufferToJson(flatbuffer.AsFlatbufferSpan(), json_options);
}

// Converts a flatbuffer::Table to JSON.
template <typename T>
typename std::enable_if<
    std::is_base_of<flatbuffers::Table, T>::value,
    std::string>::type inline FlatbufferToJson(const T *flatbuffer,
                                               JsonOptions json_options = {}) {
  return TableFlatbufferToJson(
      reinterpret_cast<const flatbuffers::Table *>(flatbuffer),
      Flatbuffer<T>::MiniReflectTypeTable(), json_options);
}

std::string FlatbufferToJson(const reflection::Schema *schema,
                             const uint8_t *data,
                             JsonOptions json_options = {});

void FlatbufferToJson(FastStringBuilder *builder,
                      const reflection::Schema *schema, const uint8_t *data,
                      JsonOptions json_options = {});

// Writes a Flatbuffer to a file, or dies.
template <typename T>
inline void WriteFlatbufferToJson(std::string_view filename, const T *msg) {
  std::ofstream json_file(std::string(filename), std::ios::out);
  CHECK(json_file) << ": Couldn't open " << filename;
  json_file << FlatbufferToJson(msg);
  json_file.close();
}

template <typename T>
inline void WriteFlatbufferToJson(std::string_view filename,
                                  const Flatbuffer<T> &msg) {
  WriteFlatbufferToJson(filename, &msg.message());
}

// Writes a NonSizePrefixedFlatbuffer to a binary file, or dies.
template <typename T>
inline void WriteFlatbufferToFile(std::string_view filename,
                                  const NonSizePrefixedFlatbuffer<T> &msg) {
  std::ofstream file(std::string(filename),
                     std::ios::out | std::ofstream::binary);
  CHECK(file) << ": Couldn't open " << filename;
  std::copy(msg.span().begin(), msg.span().end(),
            std::ostreambuf_iterator<char>(file));
}

// Parses a file as JSON and returns the corresponding Flatbuffer. Dies if
// reading the file fails, returns an empty buffer if the contents are invalid.
template <typename T>
inline FlatbufferDetachedBuffer<T> JsonFileToFlatbuffer(
    const std::string_view path) {
  return FlatbufferDetachedBuffer<T>(
      JsonToFlatbuffer<T>(util::ReadFileToStringOrDie(path)));
}

// Parses a file as a binary flatbuffer or dies.
template <typename T>
inline FlatbufferVector<T> FileToFlatbuffer(const std::string_view path) {
  const std::string data_string = util::ReadFileToStringOrDie(path);
  ResizeableBuffer data;
  data.resize(data_string.size());
  memcpy(data.data(), data_string.data(), data_string.size());
  return FlatbufferVector<T>(std::move(data));
}

}  // namespace aos

#endif  // AOS_JSON_TO_FLATBUFFER_H_
