//===- offload-tblgen/DocGen.cpp - Tablegen backend for Offload header ----===//
//
// 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 is a Tablegen backend that produces the contents of the Offload API
// specification. The generated reStructuredText is Sphinx compatible, see
// https://www.sphinx-doc.org/en/master/usage/domains/c.html for further
// details on the C language domain.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"

#include "GenCommon.hpp"
#include "RecordTypes.hpp"

using namespace llvm;
using namespace offload::tblgen;

namespace {
std::string makeFunctionSignature(StringRef RetTy, StringRef Name,
                                  ArrayRef<ParamRec> Params) {
  std::string S;
  raw_string_ostream OS{S};
  OS << RetTy << " " << Name << "(";
  for (const ParamRec &Param : Params) {
    OS << Param.getType() << " " << Param.getName();
    if (Param != Params.back()) {
      OS << ", ";
    }
  }
  OS << ")";
  return S;
}

std::string makeDoubleBackticks(StringRef R) {
  std::string S;
  for (char C : R) {
    if (C == '`') {
      S.push_back('`');
    }
    S.push_back(C);
  }
  return S;
}

void processMacro(const MacroRec &M, raw_ostream &OS) {
  OS << formatv(".. c:macro:: {0}\n\n", M.getNameWithArgs());
  OS << "  " << M.getDesc() << "\n\n";
}

void processTypedef(const TypedefRec &T, raw_ostream &OS) {
  OS << formatv(".. c:type:: {0} {1}\n\n", T.getValue(), T.getName());
  OS << "  " << T.getDesc() << "\n\n";
}

void processHandle(const HandleRec &H, raw_ostream &OS) {

  OS << formatv(".. c:type:: struct {0} *{1}\n\n", getHandleImplName(H),
                H.getName());
  OS << "  " << H.getDesc() << "\n\n";
}

void processFptrTypedef(const FptrTypedefRec &F, raw_ostream &OS) {
  OS << ".. c:type:: "
     << makeFunctionSignature(F.getReturn(),
                              StringRef{formatv("(*{0})", F.getName())},
                              F.getParams())
     << "\n\n";
  for (const ParamRec &P : F.getParams()) {
    OS << formatv("  :param {0}: {1}\n", P.getName(), P.getDesc());
  }
  OS << "\n";
}

void processEnum(const EnumRec &E, raw_ostream &OS) {
  OS << formatv(".. c:enum:: {0}\n\n", E.getName());
  OS << "  " << E.getDesc() << "\n\n";
  for (const EnumValueRec Etor : E.getValues()) {
    OS << formatv("  .. c:enumerator:: {0}_{1}\n\n", E.getEnumValNamePrefix(),
                  Etor.getName());
    OS << "    ";
    if (E.isTyped()) {
      OS << ":c:expr:`" << Etor.getTaggedType() << "` — ";
    }
    OS << Etor.getDesc() << "\n\n";
  }
}

void processStruct(const StructRec &S, raw_ostream &OS) {
  OS << formatv(".. c:struct:: {0}\n\n", S.getName());
  OS << "  " << S.getDesc() << "\n\n";
  for (const StructMemberRec &M : S.getMembers()) {
    OS << formatv("  .. c:member:: {0} {1}\n\n", M.getType(), M.getName());
    OS << "    " << M.getDesc() << "\n\n";
  }
}

void processFunction(const FunctionRec &F, raw_ostream &OS) {
  OS << ".. c:function:: "
     << makeFunctionSignature({formatv("{0}_result_t", PrefixLower)},
                              F.getName(), F.getParams())
     << "\n\n";

  OS << "  " << F.getDesc() << "\n\n";
  // Details starting with "- " are bullets, anything else is a paragraph.
  bool PrevWasBullet = false;
  for (auto [I, D] : llvm::enumerate(F.getDetails())) {
    bool IsBullet = D.starts_with("- ");
    if (I > 0 && (!IsBullet || !PrevWasBullet))
      OS << "\n";
    if (IsBullet)
      OS << "  * " << D.drop_front(2) << "\n";
    else
      OS << "  " << D << "\n";
    PrevWasBullet = IsBullet;
  }
  if (!F.getDetails().empty()) {
    OS << "\n";
  }

  for (const ParamRec &P : F.getParams()) {
    OS << formatv("  :param {0}: {1}\n", P.getName(), P.getDesc());
  }

  for (const ReturnRec &R : F.getReturns()) {
    OS << formatv("  :retval {0}:\n", R.getValue());
    for (StringRef C : R.getConditions()) {
      OS << "    * ";
      if (ReturnRec::isValidationCondition(C)) {
        OS << ":c:expr:" << C;
      } else {
        OS << makeDoubleBackticks(C);
      }
      OS << "\n";
    }
  }
  OS << "\n";
}
} // namespace

void EmitOffloadDoc(const RecordKeeper &Records, raw_ostream &OS) {
  OS << "Offload API\n";
  OS << "===========\n\n";

  ArrayRef<const Record *> Macros = Records.getAllDerivedDefinitions("Macro");
  if (!Macros.empty()) {
    OS << "Macros\n";
    OS << "------\n\n";
    for (const Record *M : Macros) {
      processMacro(MacroRec{M}, OS);
    }
  }

  ArrayRef<const Record *> Handles = Records.getAllDerivedDefinitions("Handle");
  ArrayRef<const Record *> Typedefs =
      Records.getAllDerivedDefinitions("Typedef");
  ArrayRef<const Record *> FptrTypedefs =
      Records.getAllDerivedDefinitions("FptrTypedef");
  if (!Handles.empty() || !Typedefs.empty() || !FptrTypedefs.empty()) {
    OS << "Type Definitions\n";
    OS << "----------------\n\n";
    for (const Record *H : Handles) {
      processHandle(HandleRec{H}, OS);
    }
    for (const Record *T : Typedefs) {
      processTypedef(TypedefRec{T}, OS);
    }
    for (const Record *F : FptrTypedefs) {
      processFptrTypedef(FptrTypedefRec{F}, OS);
    }
  }

  ArrayRef<const Record *> Enums = Records.getAllDerivedDefinitions("Enum");
  OS << "Enums\n";
  OS << "-----\n\n";
  if (!Enums.empty()) {
    for (const Record *E : Enums) {
      processEnum(EnumRec{E}, OS);
    }
  }

  ArrayRef<const Record *> Structs = Records.getAllDerivedDefinitions("Struct");
  if (!Structs.empty()) {
    OS << "Structs\n";
    OS << "-------\n\n";
    for (const Record *S : Structs) {
      processStruct(StructRec{S}, OS);
    }
  }

  ArrayRef<const Record *> Functions =
      Records.getAllDerivedDefinitions("Function");
  if (!Functions.empty()) {
    OS << "Functions\n";
    OS << "---------\n\n";
    for (const Record *F : Functions) {
      processFunction(FunctionRec{F}, OS);
    }
  }
}
