//===- TensorSpec.cpp - tensor type abstraction ---------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Implementation file for the abstraction of a tensor type, and JSON loading
// utils.
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h"

#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/TensorSpec.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/raw_ostream.h"
#include <array>
#include <cassert>
#include <numeric>

using namespace llvm;

namespace llvm {

#define TFUTILS_GETDATATYPE_IMPL(T, E)                                         \
  template <> TensorType TensorSpec::getDataType<T>() { return TensorType::E; }

SUPPORTED_TENSOR_TYPES(TFUTILS_GETDATATYPE_IMPL)

#undef TFUTILS_GETDATATYPE_IMPL

static std::array<std::string, static_cast<size_t>(TensorType::Total)>
    TensorTypeNames{"INVALID",
#define TFUTILS_GETNAME_IMPL(T, _) #T,
                    SUPPORTED_TENSOR_TYPES(TFUTILS_GETNAME_IMPL)
#undef TFUTILS_GETNAME_IMPL
    };

StringRef toString(TensorType TT) {
  return TensorTypeNames[static_cast<size_t>(TT)];
}

void TensorSpec::toJSON(json::OStream &OS) const {
  OS.object([&]() {
    OS.attribute("name", name());
    OS.attribute("type", toString(type()));
    OS.attribute("port", port());
    OS.attributeArray("shape", [&]() {
      for (size_t D : shape())
        OS.value(static_cast<int64_t>(D));
    });
  });
}

TensorSpec::TensorSpec(const std::string &Name, int Port, TensorType Type,
                       size_t ElementSize, const std::vector<int64_t> &Shape)
    : Name(Name), Port(Port), Type(Type), Shape(Shape),
      ElementCount(std::accumulate(Shape.begin(), Shape.end(), 1,
                                   std::multiplies<int64_t>())),
      ElementSize(ElementSize) {}

std::optional<TensorSpec> getTensorSpecFromJSON(LLVMContext &Ctx,
                                                const json::Value &Value) {
  auto EmitError =
      [&](const llvm::Twine &Message) -> std::optional<TensorSpec> {
    std::string S;
    llvm::raw_string_ostream OS(S);
    OS << Value;
    Ctx.emitError("Unable to parse JSON Value as spec (" + Message + "): " + S);
    return std::nullopt;
  };
  // FIXME: accept a Path as a parameter, and use it for error reporting.
  json::Path::Root Root("tensor_spec");
  json::ObjectMapper Mapper(Value, Root);
  if (!Mapper)
    return EmitError("Value is not a dict");

  std::string TensorName;
  int TensorPort = -1;
  std::string TensorType;
  std::vector<int64_t> TensorShape;

  if (!Mapper.map<std::string>("name", TensorName))
    return EmitError("'name' property not present or not a string");
  if (!Mapper.map<std::string>("type", TensorType))
    return EmitError("'type' property not present or not a string");
  if (!Mapper.map<int>("port", TensorPort))
    return EmitError("'port' property not present or not an int");
  if (!Mapper.map<std::vector<int64_t>>("shape", TensorShape))
    return EmitError("'shape' property not present or not an int array");

#define PARSE_TYPE(T, E)                                                       \
  if (TensorType == #T)                                                        \
    return TensorSpec::createSpec<T>(TensorName, TensorShape, TensorPort);
  SUPPORTED_TENSOR_TYPES(PARSE_TYPE)
#undef PARSE_TYPE
  return std::nullopt;
}

std::string tensorValueToString(const char *Buffer, const TensorSpec &Spec) {
  switch (Spec.type()) {
#define _IMR_DBG_PRINTER(T, N)                                                 \
  case TensorType::N: {                                                        \
    const T *TypedBuff = reinterpret_cast<const T *>(Buffer);                  \
    auto R = llvm::make_range(TypedBuff, TypedBuff + Spec.getElementCount());  \
    return llvm::join(                                                         \
        llvm::map_range(R, [](T V) { return std::to_string(V); }), ",");       \
  }
    SUPPORTED_TENSOR_TYPES(_IMR_DBG_PRINTER)
#undef _IMR_DBG_PRINTER
  case TensorType::Total:
  case TensorType::Invalid:
    llvm_unreachable("invalid tensor type");
  }
  // To appease warnings about not all control paths returning a value.
  return "";
}

} // namespace llvm
