//===-- Implementation of the main header generation class ----------------===//
//
// 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 "Generator.h"

#include "IncludeFileCommand.h"
#include "PublicAPICommand.h"
#include "utils/LibcTableGenUtil/APIIndexer.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"

#include <cstdlib>
#include <memory>

static const char CommandPrefix[] = "%%";
static const size_t CommandPrefixSize = llvm::StringRef(CommandPrefix).size();

static const char CommentPrefix[] = "<!>";

static const char ParamNamePrefix[] = "${";
static const size_t ParamNamePrefixSize =
    llvm::StringRef(ParamNamePrefix).size();
static const char ParamNameSuffix[] = "}";
static const size_t ParamNameSuffixSize =
    llvm::StringRef(ParamNameSuffix).size();

namespace llvm_libc {

Command *Generator::getCommandHandler(llvm::StringRef CommandName) {
  if (CommandName == IncludeFileCommand::Name) {
    if (!IncludeFileCmd)
      IncludeFileCmd = std::make_unique<IncludeFileCommand>();
    return IncludeFileCmd.get();
  } else if (CommandName == PublicAPICommand::Name) {
    if (!PublicAPICmd)
      PublicAPICmd = std::make_unique<PublicAPICommand>(EntrypointNameList);
    return PublicAPICmd.get();
  } else {
    return nullptr;
  }
}

void Generator::parseCommandArgs(llvm::StringRef ArgStr, ArgVector &Args) {
  if (!ArgStr.contains(',') && ArgStr.trim(' ').trim('\t').size() == 0) {
    // If it is just space between the parenthesis
    return;
  }

  ArgStr.split(Args, ",");
  for (llvm::StringRef &A : Args) {
    A = A.trim(' ');
    if (A.starts_with(ParamNamePrefix) && A.ends_with(ParamNameSuffix)) {
      A = A.drop_front(ParamNamePrefixSize).drop_back(ParamNameSuffixSize);
      A = ArgMap[std::string(A)];
    }
  }
}

void Generator::generate(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) {
  auto DefFileBuffer = llvm::MemoryBuffer::getFile(HeaderDefFile);
  if (!DefFileBuffer) {
    llvm::errs() << "Unable to open " << HeaderDefFile << ".\n";
    std::exit(1);
  }
  llvm::SourceMgr SrcMgr;
  unsigned DefFileID = SrcMgr.AddNewSourceBuffer(
      std::move(DefFileBuffer.get()), llvm::SMLoc::getFromPointer(nullptr));

  llvm::StringRef Content = SrcMgr.getMemoryBuffer(DefFileID)->getBuffer();
  while (true) {
    std::pair<llvm::StringRef, llvm::StringRef> P = Content.split('\n');
    Content = P.second;

    llvm::StringRef Line = P.first.trim(' ');
    if (Line.starts_with(CommandPrefix)) {
      Line = Line.drop_front(CommandPrefixSize);

      P = Line.split("(");
      if (P.second.empty() || P.second[P.second.size() - 1] != ')') {
        SrcMgr.PrintMessage(llvm::SMLoc::getFromPointer(P.second.data()),
                            llvm::SourceMgr::DK_Error,
                            "Command argument list should begin with '(' "
                            "and end with ')'.");
        std::exit(1);
      }
      llvm::StringRef CommandName = P.first;
      Command *Cmd = getCommandHandler(CommandName);
      if (Cmd == nullptr) {
        SrcMgr.PrintMessage(llvm::SMLoc::getFromPointer(CommandName.data()),
                            llvm::SourceMgr::DK_Error,
                            "Unknown command '%%" + CommandName + "'.");
        std::exit(1);
      }

      llvm::StringRef ArgStr = P.second.drop_back(1);
      ArgVector Args;
      parseCommandArgs(ArgStr, Args);

      Command::ErrorReporter Reporter(
          llvm::SMLoc::getFromPointer(CommandName.data()), SrcMgr);
      Cmd->run(OS, Args, StdHeader, Records, Reporter);
    } else if (!Line.starts_with(CommentPrefix)) {
      // There is no comment or command on this line so we just write it as is.
      OS << P.first << "\n";
    }

    if (P.second.empty())
      break;
  }
}

void Generator::generateDecls(llvm::raw_ostream &OS,
                              llvm::RecordKeeper &Records) {

  OS << "//===-- C standard declarations for " << StdHeader << " "
     << std::string(80 - (42 + StdHeader.size()), '-') << "===//\n"
     << "//\n"
     << "// Part of the LLVM Project, under the Apache License v2.0 with LLVM "
        "Exceptions.\n"
     << "// See https://llvm.org/LICENSE.txt for license information.\n"
     << "// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n"
     << "//\n"
     << "//"
        "===-------------------------------------------------------------------"
        "---===//\n\n";

  std::string HeaderGuard(StdHeader.size(), '\0');
  llvm::transform(StdHeader, HeaderGuard.begin(), [](const char C) -> char {
    return !isalnum(C) ? '_' : llvm::toUpper(C);
  });
  OS << "#ifndef __LLVM_LIBC_DECLARATIONS_" << HeaderGuard << "\n"
     << "#define __LLVM_LIBC_DECLARATIONS_" << HeaderGuard << "\n\n";

  OS << "#ifndef __LIBC_ATTRS\n"
     << "#define __LIBC_ATTRS\n"
     << "#endif\n\n";

  OS << "#ifdef __cplusplus\n"
     << "extern \"C\" {\n"
     << "#endif\n\n";

  APIIndexer G(StdHeader, Records);
  for (auto &Name : EntrypointNameList) {
    // Filter out functions not exported by this header.
    if (G.FunctionSpecMap.find(Name) == G.FunctionSpecMap.end())
      continue;

    llvm::Record *FunctionSpec = G.FunctionSpecMap[Name];
    llvm::Record *RetValSpec = FunctionSpec->getValueAsDef("Return");
    llvm::Record *ReturnType = RetValSpec->getValueAsDef("ReturnType");

    OS << G.getTypeAsString(ReturnType) << " " << Name << "(";

    auto ArgsList = FunctionSpec->getValueAsListOfDefs("Args");
    for (size_t i = 0; i < ArgsList.size(); ++i) {
      llvm::Record *ArgType = ArgsList[i]->getValueAsDef("ArgType");
      OS << G.getTypeAsString(ArgType);
      if (i < ArgsList.size() - 1)
        OS << ", ";
    }

    OS << ") __LIBC_ATTRS;\n\n";
  }

  // Make another pass over entrypoints to emit object declarations.
  for (const auto &Name : EntrypointNameList) {
    if (G.ObjectSpecMap.find(Name) == G.ObjectSpecMap.end())
      continue;
    llvm::Record *ObjectSpec = G.ObjectSpecMap[Name];
    auto Type = ObjectSpec->getValueAsString("Type");
    OS << "extern " << Type << " " << Name << " __LIBC_ATTRS;\n";
  }

  // Emit a final newline if we emitted any object declarations.
  if (llvm::any_of(EntrypointNameList, [&](const std::string &Name) {
        return G.ObjectSpecMap.find(Name) != G.ObjectSpecMap.end();
      }))
    OS << "\n";

  OS << "#ifdef __cplusplus\n"
     << "}\n"
     << "#endif\n\n";
  OS << "#endif\n";
}

} // namespace llvm_libc
