//===- yaml2obj - Convert YAML to a binary object file --------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This program takes a YAML description of an object file and outputs the
// binary equivalent.
//
// This is used for writing tests that require binary files.
//
//===----------------------------------------------------------------------===//

#include "llvm/ObjectYAML/yaml2obj.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ObjectYAML/ObjectYAML.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
#include <system_error>

using namespace llvm;

namespace {
cl::OptionCategory Cat("yaml2obj Options");

cl::opt<std::string> Input(cl::Positional, cl::desc("<input file>"),
                           cl::init("-"), cl::cat(Cat));

static cl::list<std::string>
    D("D", cl::Prefix,
      cl::desc("Defined the specified macros to their specified "
               "definition. The syntax is <macro>=<definition>"),
      cl::cat(Cat));

cl::opt<bool> PreprocessOnly("E", cl::desc("Just print the preprocessed file"),
                             cl::cat(Cat));

cl::opt<unsigned>
    DocNum("docnum", cl::init(1),
           cl::desc("Read specified document from input (default = 1)"),
           cl::cat(Cat));

static cl::opt<uint64_t> MaxSize(
    "max-size", cl::init(10 * 1024 * 1024),
    cl::desc(
        "Sets the maximum allowed output size (0 means no limit) [ELF only]"),
    cl::cat(Cat));

cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"),
                                    cl::value_desc("filename"), cl::init("-"),
                                    cl::Prefix, cl::cat(Cat));
} // namespace

static std::optional<std::string> preprocess(StringRef Buf,
                                             yaml::ErrorHandler ErrHandler) {
  DenseMap<StringRef, StringRef> Defines;
  for (StringRef Define : D) {
    StringRef Macro, Definition;
    std::tie(Macro, Definition) = Define.split('=');
    if (!Define.count('=') || Macro.empty()) {
      ErrHandler("invalid syntax for -D: " + Define);
      return {};
    }
    if (!Defines.try_emplace(Macro, Definition).second) {
      ErrHandler("'" + Macro + "'" + " redefined");
      return {};
    }
  }

  std::string Preprocessed;
  while (!Buf.empty()) {
    if (Buf.starts_with("[[")) {
      size_t I = Buf.find_first_of("[]", 2);
      if (Buf.substr(I).starts_with("]]")) {
        StringRef MacroExpr = Buf.substr(2, I - 2);
        StringRef Macro;
        StringRef Default;
        std::tie(Macro, Default) = MacroExpr.split('=');

        // When the -D option is requested, we use the provided value.
        // Otherwise we use a default macro value if present.
        auto It = Defines.find(Macro);
        std::optional<StringRef> Value;
        if (It != Defines.end())
          Value = It->second;
        else if (!Default.empty() || MacroExpr.ends_with("="))
          Value = Default;

        if (Value) {
          Preprocessed += *Value;
          Buf = Buf.substr(I + 2);
          continue;
        }
      }
    }

    Preprocessed += Buf[0];
    Buf = Buf.substr(1);
  }

  return Preprocessed;
}

int main(int argc, char **argv) {
  InitLLVM X(argc, argv);
  cl::HideUnrelatedOptions(Cat);
  cl::ParseCommandLineOptions(
      argc, argv, "Create an object file from a YAML description", nullptr,
      nullptr, /*LongOptionsUseDoubleDash=*/true);

  constexpr StringRef ProgName = "yaml2obj";
  auto ErrHandler = [&](const Twine &Msg) {
    WithColor::error(errs(), ProgName) << Msg << "\n";
  };

  std::error_code EC;
  std::unique_ptr<ToolOutputFile> Out(
      new ToolOutputFile(OutputFilename, EC, sys::fs::OF_None));
  if (EC) {
    ErrHandler("failed to open '" + OutputFilename + "': " + EC.message());
    return 1;
  }

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
      MemoryBuffer::getFileOrSTDIN(Input, /*IsText=*/true);
  if (std::error_code EC = Buf.getError()) {
    WithColor::error(errs(), ProgName) << Input << ": " << EC.message() << '\n';
    return 1;
  }

  std::optional<std::string> Buffer =
      preprocess(Buf.get()->getBuffer(), ErrHandler);
  if (!Buffer)
    return 1;

  if (PreprocessOnly) {
    Out->os() << Buffer;
  } else {
    yaml::Input YIn(*Buffer);

    if (!convertYAML(YIn, Out->os(), ErrHandler, DocNum,
                     MaxSize == 0 ? UINT64_MAX : MaxSize))
      return 1;
  }

  Out->keep();
  Out->os().flush();
  return 0;
}
