//===- TBEHandler.cpp -----------------------------------------------------===//
//
// 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
//
//===-----------------------------------------------------------------------===/

#include "llvm/TextAPI/ELF/TBEHandler.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/TextAPI/ELF/ELFStub.h"

using namespace llvm;
using namespace llvm::elfabi;

LLVM_YAML_STRONG_TYPEDEF(ELFArch, ELFArchMapper)

namespace llvm {
namespace yaml {

/// YAML traits for ELFSymbolType.
template <> struct ScalarEnumerationTraits<ELFSymbolType> {
  static void enumeration(IO &IO, ELFSymbolType &SymbolType) {
    IO.enumCase(SymbolType, "NoType", ELFSymbolType::NoType);
    IO.enumCase(SymbolType, "Func", ELFSymbolType::Func);
    IO.enumCase(SymbolType, "Object", ELFSymbolType::Object);
    IO.enumCase(SymbolType, "TLS", ELFSymbolType::TLS);
    IO.enumCase(SymbolType, "Unknown", ELFSymbolType::Unknown);
    // Treat other symbol types as noise, and map to Unknown.
    if (!IO.outputting() && IO.matchEnumFallback())
      SymbolType = ELFSymbolType::Unknown;
  }
};

/// YAML traits for ELFArch.
template <> struct ScalarTraits<ELFArchMapper> {
  static void output(const ELFArchMapper &Value, void *,
                     llvm::raw_ostream &Out) {
    // Map from integer to architecture string.
    switch (Value) {
    case (ELFArch)ELF::EM_X86_64:
      Out << "x86_64";
      break;
    case (ELFArch)ELF::EM_AARCH64:
      Out << "AArch64";
      break;
    case (ELFArch)ELF::EM_NONE:
    default:
      Out << "Unknown";
    }
  }

  static StringRef input(StringRef Scalar, void *, ELFArchMapper &Value) {
    // Map from architecture string to integer.
    Value = StringSwitch<ELFArch>(Scalar)
                .Case("x86_64", ELF::EM_X86_64)
                .Case("AArch64", ELF::EM_AARCH64)
                .Case("Unknown", ELF::EM_NONE)
                .Default(ELF::EM_NONE);

    // Returning empty StringRef indicates successful parse.
    return StringRef();
  }

  // Don't place quotation marks around architecture value.
  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};

/// YAML traits for TbeVersion.
template <> struct ScalarTraits<VersionTuple> {
  static void output(const VersionTuple &Value, void *,
                     llvm::raw_ostream &Out) {
    Out << Value.getAsString();
  }

  static StringRef input(StringRef Scalar, void *, VersionTuple &Value) {
    if (Value.tryParse(Scalar))
      return StringRef("Can't parse version: invalid version format.");

    if (Value > TBEVersionCurrent)
      return StringRef("Unsupported TBE version.");

    // Returning empty StringRef indicates successful parse.
    return StringRef();
  }

  // Don't place quotation marks around version value.
  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};

/// YAML traits for ELFSymbol.
template <> struct MappingTraits<ELFSymbol> {
  static void mapping(IO &IO, ELFSymbol &Symbol) {
    IO.mapRequired("Type", Symbol.Type);
    // The need for symbol size depends on the symbol type.
    if (Symbol.Type == ELFSymbolType::NoType) {
      IO.mapOptional("Size", Symbol.Size, (uint64_t)0);
    } else if (Symbol.Type == ELFSymbolType::Func) {
      Symbol.Size = 0;
    } else {
      IO.mapRequired("Size", Symbol.Size);
    }
    IO.mapOptional("Undefined", Symbol.Undefined, false);
    IO.mapOptional("Weak", Symbol.Weak, false);
    IO.mapOptional("Warning", Symbol.Warning);
  }

  // Compacts symbol information into a single line.
  static const bool flow = true;
};

/// YAML traits for set of ELFSymbols.
template <> struct CustomMappingTraits<std::set<ELFSymbol>> {
  static void inputOne(IO &IO, StringRef Key, std::set<ELFSymbol> &Set) {
    ELFSymbol Sym(Key.str());
    IO.mapRequired(Key.str().c_str(), Sym);
    Set.insert(Sym);
  }

  static void output(IO &IO, std::set<ELFSymbol> &Set) {
    for (auto &Sym : Set)
      IO.mapRequired(Sym.Name.c_str(), const_cast<ELFSymbol &>(Sym));
  }
};

/// YAML traits for ELFStub objects.
template <> struct MappingTraits<ELFStub> {
  static void mapping(IO &IO, ELFStub &Stub) {
    if (!IO.mapTag("!tapi-tbe", true))
      IO.setError("Not a .tbe YAML file.");
    IO.mapRequired("TbeVersion", Stub.TbeVersion);
    IO.mapOptional("SoName", Stub.SoName);
    IO.mapRequired("Arch", (ELFArchMapper &)Stub.Arch);
    IO.mapOptional("NeededLibs", Stub.NeededLibs);
    IO.mapRequired("Symbols", Stub.Symbols);
  }
};

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

Expected<std::unique_ptr<ELFStub>> elfabi::readTBEFromBuffer(StringRef Buf) {
  yaml::Input YamlIn(Buf);
  std::unique_ptr<ELFStub> Stub(new ELFStub());
  YamlIn >> *Stub;
  if (std::error_code Err = YamlIn.error())
    return createStringError(Err, "YAML failed reading as TBE");

  return std::move(Stub);
}

Error elfabi::writeTBEToOutputStream(raw_ostream &OS, const ELFStub &Stub) {
  yaml::Output YamlOut(OS, NULL, /*WrapColumn =*/0);

  YamlOut << const_cast<ELFStub &>(Stub);
  return Error::success();
}
