//===- lib/DebugInfo/Symbolize/DIPrinter.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
//
//===----------------------------------------------------------------------===//
//
// This file defines the DIPrinter class, which is responsible for printing
// structures defined in DebugInfo/DIContext.h
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/Symbolize/DIPrinter.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>

namespace llvm {
namespace symbolize {

class SourceCode {
  std::unique_ptr<MemoryBuffer> MemBuf;

  std::optional<StringRef>
  load(StringRef FileName, const std::optional<StringRef> &EmbeddedSource) {
    if (Lines <= 0)
      return std::nullopt;

    if (EmbeddedSource)
      return EmbeddedSource;
    else {
      ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
          MemoryBuffer::getFile(FileName);
      if (!BufOrErr)
        return std::nullopt;
      MemBuf = std::move(*BufOrErr);
      return MemBuf->getBuffer();
    }
  }

  std::optional<StringRef> pruneSource(const std::optional<StringRef> &Source) {
    if (!Source)
      return std::nullopt;
    size_t FirstLinePos = StringRef::npos, Pos = 0;
    for (int64_t L = 1; L <= LastLine; ++L, ++Pos) {
      if (L == FirstLine)
        FirstLinePos = Pos;
      Pos = Source->find('\n', Pos);
      if (Pos == StringRef::npos)
        break;
    }
    if (FirstLinePos == StringRef::npos)
      return std::nullopt;
    return Source->substr(FirstLinePos, (Pos == StringRef::npos)
                                            ? StringRef::npos
                                            : Pos - FirstLinePos);
  }

public:
  const int64_t Line;
  const int Lines;
  const int64_t FirstLine;
  const int64_t LastLine;
  const std::optional<StringRef> PrunedSource;

  SourceCode(StringRef FileName, int64_t Line, int Lines,
             const std::optional<StringRef> &EmbeddedSource =
                 std::optional<StringRef>())
      : Line(Line), Lines(Lines),
        FirstLine(std::max(static_cast<int64_t>(1), Line - Lines / 2)),
        LastLine(FirstLine + Lines - 1),
        PrunedSource(pruneSource(load(FileName, EmbeddedSource))) {}

  void format(raw_ostream &OS) {
    if (!PrunedSource)
      return;
    size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
    int64_t L = FirstLine;
    for (size_t Pos = 0; Pos < PrunedSource->size(); ++L) {
      size_t PosEnd = PrunedSource->find('\n', Pos);
      StringRef String = PrunedSource->substr(
          Pos, (PosEnd == StringRef::npos) ? StringRef::npos : (PosEnd - Pos));
      if (String.endswith("\r"))
        String = String.drop_back(1);
      OS << format_decimal(L, MaxLineNumberWidth);
      if (L == Line)
        OS << " >: ";
      else
        OS << "  : ";
      OS << String << '\n';
      if (PosEnd == StringRef::npos)
        break;
      Pos = PosEnd + 1;
    }
  }
};

void PlainPrinterBase::printHeader(uint64_t Address) {
  if (Config.PrintAddress) {
    OS << "0x";
    OS.write_hex(Address);
    StringRef Delimiter = Config.Pretty ? ": " : "\n";
    OS << Delimiter;
  }
}

// Prints source code around in the FileName the Line.
void PlainPrinterBase::printContext(SourceCode SourceCode) {
  SourceCode.format(OS);
}

void PlainPrinterBase::printFunctionName(StringRef FunctionName, bool Inlined) {
  if (Config.PrintFunctions) {
    if (FunctionName == DILineInfo::BadString)
      FunctionName = DILineInfo::Addr2LineBadString;
    StringRef Delimiter = Config.Pretty ? " at " : "\n";
    StringRef Prefix = (Config.Pretty && Inlined) ? " (inlined by) " : "";
    OS << Prefix << FunctionName << Delimiter;
  }
}

void LLVMPrinter::printSimpleLocation(StringRef Filename,
                                      const DILineInfo &Info) {
  OS << Filename << ':' << Info.Line << ':' << Info.Column << '\n';
  printContext(
      SourceCode(Filename, Info.Line, Config.SourceContextLines, Info.Source));
}

void GNUPrinter::printSimpleLocation(StringRef Filename,
                                     const DILineInfo &Info) {
  OS << Filename << ':' << Info.Line;
  if (Info.Discriminator)
    OS << " (discriminator " << Info.Discriminator << ')';
  OS << '\n';
  printContext(
      SourceCode(Filename, Info.Line, Config.SourceContextLines, Info.Source));
}

void PlainPrinterBase::printVerbose(StringRef Filename,
                                    const DILineInfo &Info) {
  OS << "  Filename: " << Filename << '\n';
  if (Info.StartLine) {
    OS << "  Function start filename: " << Info.StartFileName << '\n';
    OS << "  Function start line: " << Info.StartLine << '\n';
  }
  printStartAddress(Info);
  OS << "  Line: " << Info.Line << '\n';
  OS << "  Column: " << Info.Column << '\n';
  if (Info.Discriminator)
    OS << "  Discriminator: " << Info.Discriminator << '\n';
}

void LLVMPrinter::printStartAddress(const DILineInfo &Info) {
  if (Info.StartAddress) {
    OS << "  Function start address: 0x";
    OS.write_hex(*Info.StartAddress);
    OS << '\n';
  }
}

void LLVMPrinter::printFooter() { OS << '\n'; }

void PlainPrinterBase::print(const DILineInfo &Info, bool Inlined) {
  printFunctionName(Info.FunctionName, Inlined);
  StringRef Filename = Info.FileName;
  if (Filename == DILineInfo::BadString)
    Filename = DILineInfo::Addr2LineBadString;
  if (Config.Verbose)
    printVerbose(Filename, Info);
  else
    printSimpleLocation(Filename, Info);
}

void PlainPrinterBase::print(const Request &Request, const DILineInfo &Info) {
  printHeader(*Request.Address);
  print(Info, false);
  printFooter();
}

void PlainPrinterBase::print(const Request &Request,
                             const DIInliningInfo &Info) {
  printHeader(*Request.Address);
  uint32_t FramesNum = Info.getNumberOfFrames();
  if (FramesNum == 0)
    print(DILineInfo(), false);
  else
    for (uint32_t I = 0; I < FramesNum; ++I)
      print(Info.getFrame(I), I > 0);
  printFooter();
}

void PlainPrinterBase::print(const Request &Request, const DIGlobal &Global) {
  printHeader(*Request.Address);
  StringRef Name = Global.Name;
  if (Name == DILineInfo::BadString)
    Name = DILineInfo::Addr2LineBadString;
  OS << Name << "\n";
  OS << Global.Start << " " << Global.Size << "\n";
  if (Global.DeclFile.empty())
    OS << "??:?\n";
  else
    OS << Global.DeclFile << ":" << Global.DeclLine << "\n";
  printFooter();
}

void PlainPrinterBase::print(const Request &Request,
                             const std::vector<DILocal> &Locals) {
  printHeader(*Request.Address);
  if (Locals.empty())
    OS << DILineInfo::Addr2LineBadString << '\n';
  else
    for (const DILocal &L : Locals) {
      if (L.FunctionName.empty())
        OS << DILineInfo::Addr2LineBadString;
      else
        OS << L.FunctionName;
      OS << '\n';

      if (L.Name.empty())
        OS << DILineInfo::Addr2LineBadString;
      else
        OS << L.Name;
      OS << '\n';

      if (L.DeclFile.empty())
        OS << DILineInfo::Addr2LineBadString;
      else
        OS << L.DeclFile;

      OS << ':' << L.DeclLine << '\n';

      if (L.FrameOffset)
        OS << *L.FrameOffset;
      else
        OS << DILineInfo::Addr2LineBadString;
      OS << ' ';

      if (L.Size)
        OS << *L.Size;
      else
        OS << DILineInfo::Addr2LineBadString;
      OS << ' ';

      if (L.TagOffset)
        OS << *L.TagOffset;
      else
        OS << DILineInfo::Addr2LineBadString;
      OS << '\n';
    }
  printFooter();
}

void PlainPrinterBase::printInvalidCommand(const Request &Request,
                                           StringRef Command) {
  OS << Command << '\n';
}

bool PlainPrinterBase::printError(const Request &Request,
                                  const ErrorInfoBase &ErrorInfo,
                                  StringRef ErrorBanner) {
  ES << ErrorBanner;
  ErrorInfo.log(ES);
  ES << '\n';
  // Print an empty struct too.
  return true;
}

static std::string toHex(uint64_t V) {
  return ("0x" + Twine::utohexstr(V)).str();
}

static json::Object toJSON(const Request &Request, StringRef ErrorMsg = "") {
  json::Object Json({{"ModuleName", Request.ModuleName.str()}});
  if (Request.Address)
    Json["Address"] = toHex(*Request.Address);
  if (!ErrorMsg.empty())
    Json["Error"] = json::Object({{"Message", ErrorMsg.str()}});
  return Json;
}

void JSONPrinter::print(const Request &Request, const DILineInfo &Info) {
  DIInliningInfo InliningInfo;
  InliningInfo.addFrame(Info);
  print(Request, InliningInfo);
}

void JSONPrinter::print(const Request &Request, const DIInliningInfo &Info) {
  json::Array Array;
  for (uint32_t I = 0, N = Info.getNumberOfFrames(); I < N; ++I) {
    const DILineInfo &LineInfo = Info.getFrame(I);
    json::Object Object(
        {{"FunctionName", LineInfo.FunctionName != DILineInfo::BadString
                              ? LineInfo.FunctionName
                              : ""},
         {"StartFileName", LineInfo.StartFileName != DILineInfo::BadString
                               ? LineInfo.StartFileName
                               : ""},
         {"StartLine", LineInfo.StartLine},
         {"StartAddress",
          LineInfo.StartAddress ? toHex(*LineInfo.StartAddress) : ""},
         {"FileName",
          LineInfo.FileName != DILineInfo::BadString ? LineInfo.FileName : ""},
         {"Line", LineInfo.Line},
         {"Column", LineInfo.Column},
         {"Discriminator", LineInfo.Discriminator}});
    SourceCode SourceCode(LineInfo.FileName, LineInfo.Line,
                          Config.SourceContextLines, LineInfo.Source);
    std::string FormattedSource;
    raw_string_ostream Stream(FormattedSource);
    SourceCode.format(Stream);
    if (!FormattedSource.empty())
      Object["Source"] = std::move(FormattedSource);
    Array.push_back(std::move(Object));
  }
  json::Object Json = toJSON(Request);
  Json["Symbol"] = std::move(Array);
  if (ObjectList)
    ObjectList->push_back(std::move(Json));
  else
    printJSON(std::move(Json));
}

void JSONPrinter::print(const Request &Request, const DIGlobal &Global) {
  json::Object Data(
      {{"Name", Global.Name != DILineInfo::BadString ? Global.Name : ""},
       {"Start", toHex(Global.Start)},
       {"Size", toHex(Global.Size)}});
  json::Object Json = toJSON(Request);
  Json["Data"] = std::move(Data);
  if (ObjectList)
    ObjectList->push_back(std::move(Json));
  else
    printJSON(std::move(Json));
}

void JSONPrinter::print(const Request &Request,
                        const std::vector<DILocal> &Locals) {
  json::Array Frame;
  for (const DILocal &Local : Locals) {
    json::Object FrameObject(
        {{"FunctionName", Local.FunctionName},
         {"Name", Local.Name},
         {"DeclFile", Local.DeclFile},
         {"DeclLine", int64_t(Local.DeclLine)},
         {"Size", Local.Size ? toHex(*Local.Size) : ""},
         {"TagOffset", Local.TagOffset ? toHex(*Local.TagOffset) : ""}});
    if (Local.FrameOffset)
      FrameObject["FrameOffset"] = *Local.FrameOffset;
    Frame.push_back(std::move(FrameObject));
  }
  json::Object Json = toJSON(Request);
  Json["Frame"] = std::move(Frame);
  if (ObjectList)
    ObjectList->push_back(std::move(Json));
  else
    printJSON(std::move(Json));
}

void JSONPrinter::printInvalidCommand(const Request &Request,
                                      StringRef Command) {
  printError(Request,
             StringError("unable to parse arguments: " + Command,
                         std::make_error_code(std::errc::invalid_argument)),
             "");
}

bool JSONPrinter::printError(const Request &Request,
                             const ErrorInfoBase &ErrorInfo,
                             StringRef ErrorBanner) {
  json::Object Json = toJSON(Request, ErrorInfo.message());
  if (ObjectList)
    ObjectList->push_back(std::move(Json));
  else
    printJSON(std::move(Json));
  return false;
}

void JSONPrinter::listBegin() {
  assert(!ObjectList);
  ObjectList = std::make_unique<json::Array>();
}

void JSONPrinter::listEnd() {
  assert(ObjectList);
  printJSON(std::move(*ObjectList));
  ObjectList.reset();
}

} // end namespace symbolize
} // end namespace llvm
