//===- BytesOutputStyle.cpp ----------------------------------- *- C++ --*-===//
//
// 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 "BytesOutputStyle.h"

#include "StreamUtil.h"
#include "llvm-pdbutil.h"

#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;

namespace {
struct StreamSpec {
  uint32_t SI = 0;
  uint32_t Begin = 0;
  uint32_t Size = 0;
};
} // namespace

static Expected<StreamSpec> parseStreamSpec(StringRef Str) {
  StreamSpec Result;
  if (Str.consumeInteger(0, Result.SI))
    return make_error<RawError>(raw_error_code::invalid_format,
                                "Invalid Stream Specification");
  if (Str.consume_front(":")) {
    if (Str.consumeInteger(0, Result.Begin))
      return make_error<RawError>(raw_error_code::invalid_format,
                                  "Invalid Stream Specification");
  }
  if (Str.consume_front("@")) {
    if (Str.consumeInteger(0, Result.Size))
      return make_error<RawError>(raw_error_code::invalid_format,
                                  "Invalid Stream Specification");
  }

  if (!Str.empty())
    return make_error<RawError>(raw_error_code::invalid_format,
                                "Invalid Stream Specification");
  return Result;
}

static SmallVector<StreamSpec, 2> parseStreamSpecs(LinePrinter &P) {
  SmallVector<StreamSpec, 2> Result;

  for (auto &Str : opts::bytes::DumpStreamData) {
    auto ESS = parseStreamSpec(Str);
    if (!ESS) {
      P.formatLine("Error parsing stream spec {0}: {1}", Str,
                   toString(ESS.takeError()));
      continue;
    }
    Result.push_back(*ESS);
  }
  return Result;
}

static void printHeader(LinePrinter &P, const Twine &S) {
  P.NewLine();
  P.formatLine("{0,=60}", S);
  P.formatLine("{0}", fmt_repeat('=', 60));
}

BytesOutputStyle::BytesOutputStyle(PDBFile &File)
    : File(File), P(2, false, outs(), opts::Filters) {}

Error BytesOutputStyle::dump() {

  if (opts::bytes::DumpBlockRange) {
    auto &R = *opts::bytes::DumpBlockRange;
    uint32_t Max = R.Max.value_or(R.Min);

    if (Max < R.Min)
      return make_error<StringError>(
          "Invalid block range specified.  Max < Min",
          inconvertibleErrorCode());
    if (Max >= File.getBlockCount())
      return make_error<StringError>(
          "Invalid block range specified.  Requested block out of bounds",
          inconvertibleErrorCode());

    dumpBlockRanges(R.Min, Max);
    P.NewLine();
  }

  if (opts::bytes::DumpByteRange) {
    auto &R = *opts::bytes::DumpByteRange;
    uint32_t Max = R.Max.value_or(File.getFileSize());

    if (Max < R.Min)
      return make_error<StringError>("Invalid byte range specified.  Max < Min",
                                     inconvertibleErrorCode());
    if (Max >= File.getFileSize())
      return make_error<StringError>(
          "Invalid byte range specified.  Requested byte larger than file size",
          inconvertibleErrorCode());

    dumpByteRanges(R.Min, Max);
    P.NewLine();
  }

  if (opts::bytes::Fpm) {
    dumpFpm();
    P.NewLine();
  }

  if (!opts::bytes::DumpStreamData.empty()) {
    dumpStreamBytes();
    P.NewLine();
  }

  if (opts::bytes::NameMap) {
    dumpNameMap();
    P.NewLine();
  }

  if (opts::bytes::SectionContributions) {
    dumpSectionContributions();
    P.NewLine();
  }

  if (opts::bytes::SectionMap) {
    dumpSectionMap();
    P.NewLine();
  }

  if (opts::bytes::ModuleInfos) {
    dumpModuleInfos();
    P.NewLine();
  }

  if (opts::bytes::FileInfo) {
    dumpFileInfo();
    P.NewLine();
  }

  if (opts::bytes::TypeServerMap) {
    dumpTypeServerMap();
    P.NewLine();
  }

  if (opts::bytes::ECData) {
    dumpECData();
    P.NewLine();
  }

  if (!opts::bytes::TypeIndex.empty()) {
    dumpTypeIndex(StreamTPI, opts::bytes::TypeIndex);
    P.NewLine();
  }

  if (!opts::bytes::IdIndex.empty()) {
    dumpTypeIndex(StreamIPI, opts::bytes::IdIndex);
    P.NewLine();
  }

  if (opts::bytes::ModuleSyms) {
    dumpModuleSyms();
    P.NewLine();
  }

  if (opts::bytes::ModuleC11) {
    dumpModuleC11();
    P.NewLine();
  }

  if (opts::bytes::ModuleC13) {
    dumpModuleC13();
    P.NewLine();
  }

  return Error::success();
}

void BytesOutputStyle::dumpNameMap() {
  printHeader(P, "Named Stream Map");

  AutoIndent Indent(P);

  auto &InfoS = Err(File.getPDBInfoStream());
  BinarySubstreamRef NS = InfoS.getNamedStreamsBuffer();
  auto Layout = File.getStreamLayout(StreamPDB);
  P.formatMsfStreamData("Named Stream Map", File, Layout, NS);
}

void BytesOutputStyle::dumpBlockRanges(uint32_t Min, uint32_t Max) {
  printHeader(P, "MSF Blocks");

  AutoIndent Indent(P);
  for (uint32_t I = Min; I <= Max; ++I) {
    uint64_t Base = I;
    Base *= File.getBlockSize();

    auto ExpectedData = File.getBlockData(I, File.getBlockSize());
    if (!ExpectedData) {
      P.formatLine("Could not get block {0}.  Reason = {1}", I,
                   toString(ExpectedData.takeError()));
      continue;
    }
    std::string Label = formatv("Block {0}", I).str();
    P.formatBinary(Label, *ExpectedData, Base, 0);
  }
}

void BytesOutputStyle::dumpSectionContributions() {
  printHeader(P, "Section Contributions");

  AutoIndent Indent(P);

  auto &DbiS = Err(File.getPDBDbiStream());
  BinarySubstreamRef NS = DbiS.getSectionContributionData();
  auto Layout = File.getStreamLayout(StreamDBI);
  P.formatMsfStreamData("Section Contributions", File, Layout, NS);
}

void BytesOutputStyle::dumpSectionMap() {
  printHeader(P, "Section Map");

  AutoIndent Indent(P);

  auto &DbiS = Err(File.getPDBDbiStream());
  BinarySubstreamRef NS = DbiS.getSecMapSubstreamData();
  auto Layout = File.getStreamLayout(StreamDBI);
  P.formatMsfStreamData("Section Map", File, Layout, NS);
}

void BytesOutputStyle::dumpModuleInfos() {
  printHeader(P, "Module Infos");

  AutoIndent Indent(P);

  auto &DbiS = Err(File.getPDBDbiStream());
  BinarySubstreamRef NS = DbiS.getModiSubstreamData();
  auto Layout = File.getStreamLayout(StreamDBI);
  P.formatMsfStreamData("Module Infos", File, Layout, NS);
}

void BytesOutputStyle::dumpFileInfo() {
  printHeader(P, "File Info");

  AutoIndent Indent(P);

  auto &DbiS = Err(File.getPDBDbiStream());
  BinarySubstreamRef NS = DbiS.getFileInfoSubstreamData();
  auto Layout = File.getStreamLayout(StreamDBI);
  P.formatMsfStreamData("File Info", File, Layout, NS);
}

void BytesOutputStyle::dumpTypeServerMap() {
  printHeader(P, "Type Server Map");

  AutoIndent Indent(P);

  auto &DbiS = Err(File.getPDBDbiStream());
  BinarySubstreamRef NS = DbiS.getTypeServerMapSubstreamData();
  auto Layout = File.getStreamLayout(StreamDBI);
  P.formatMsfStreamData("Type Server Map", File, Layout, NS);
}

void BytesOutputStyle::dumpECData() {
  printHeader(P, "Edit and Continue Data");

  AutoIndent Indent(P);

  auto &DbiS = Err(File.getPDBDbiStream());
  BinarySubstreamRef NS = DbiS.getECSubstreamData();
  auto Layout = File.getStreamLayout(StreamDBI);
  P.formatMsfStreamData("Edit and Continue Data", File, Layout, NS);
}

void BytesOutputStyle::dumpTypeIndex(uint32_t StreamIdx,
                                     ArrayRef<uint32_t> Indices) {
  assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
  assert(!Indices.empty());

  bool IsTpi = (StreamIdx == StreamTPI);

  StringRef Label = IsTpi ? "Type (TPI) Records" : "Index (IPI) Records";
  printHeader(P, Label);
  auto &Stream = Err(IsTpi ? File.getPDBTpiStream() : File.getPDBIpiStream());

  AutoIndent Indent(P);

  auto Substream = Stream.getTypeRecordsSubstream();
  auto &Types = Err(initializeTypes(StreamIdx));
  auto Layout = File.getStreamLayout(StreamIdx);
  for (const auto &Id : Indices) {
    TypeIndex TI(Id);
    if (TI.toArrayIndex() >= Types.capacity()) {
      P.formatLine("Error: TypeIndex {0} does not exist", TI);
      continue;
    }

    auto Type = Types.getType(TI);
    uint32_t Offset = Types.getOffsetOfType(TI);
    auto OneType = Substream.slice(Offset, Type.length());
    P.formatMsfStreamData(formatv("Type {0}", TI).str(), File, Layout, OneType);
  }
}

template <typename CallbackT>
static void iterateOneModule(PDBFile &File, LinePrinter &P,
                             const DbiModuleList &Modules, uint32_t I,
                             uint32_t Digits, uint32_t IndentLevel,
                             CallbackT Callback) {
  if (I >= Modules.getModuleCount()) {
    P.formatLine("Mod {0:4} | Invalid module index ",
                 fmt_align(I, AlignStyle::Right, std::max(Digits, 4U)));
    return;
  }

  auto Modi = Modules.getModuleDescriptor(I);
  P.formatLine("Mod {0:4} | `{1}`: ",
               fmt_align(I, AlignStyle::Right, std::max(Digits, 4U)),
               Modi.getModuleName());

  uint16_t ModiStream = Modi.getModuleStreamIndex();
  AutoIndent Indent2(P, IndentLevel);
  if (ModiStream == kInvalidStreamIndex)
    return;

  auto ModStreamData = File.createIndexedStream(ModiStream);
  ModuleDebugStreamRef ModStream(Modi, std::move(ModStreamData));
  if (auto EC = ModStream.reload()) {
    P.formatLine("Could not parse debug information.");
    return;
  }
  auto Layout = File.getStreamLayout(ModiStream);
  Callback(I, ModStream, Layout);
}

template <typename CallbackT>
static void iterateModules(PDBFile &File, LinePrinter &P, uint32_t IndentLevel,
                           CallbackT Callback) {
  AutoIndent Indent(P);
  if (!File.hasPDBDbiStream()) {
    P.formatLine("DBI Stream not present");
    return;
  }

  ExitOnError Err("Unexpected error processing modules");

  auto &Stream = Err(File.getPDBDbiStream());

  const DbiModuleList &Modules = Stream.modules();

  if (opts::bytes::ModuleIndex.getNumOccurrences() > 0) {
    iterateOneModule(File, P, Modules, opts::bytes::ModuleIndex, 1, IndentLevel,
                     Callback);
  } else {
    uint32_t Count = Modules.getModuleCount();
    uint32_t Digits = NumDigits(Count);
    for (uint32_t I = 0; I < Count; ++I) {
      iterateOneModule(File, P, Modules, I, Digits, IndentLevel, Callback);
    }
  }
}

void BytesOutputStyle::dumpModuleSyms() {
  printHeader(P, "Module Symbols");

  AutoIndent Indent(P);

  iterateModules(File, P, 2,
                 [this](uint32_t Modi, const ModuleDebugStreamRef &Stream,
                        const MSFStreamLayout &Layout) {
                   auto Symbols = Stream.getSymbolsSubstream();
                   P.formatMsfStreamData("Symbols", File, Layout, Symbols);
                 });
}

void BytesOutputStyle::dumpModuleC11() {
  printHeader(P, "C11 Debug Chunks");

  AutoIndent Indent(P);

  iterateModules(File, P, 2,
                 [this](uint32_t Modi, const ModuleDebugStreamRef &Stream,
                        const MSFStreamLayout &Layout) {
                   auto Chunks = Stream.getC11LinesSubstream();
                   P.formatMsfStreamData("C11 Debug Chunks", File, Layout,
                                         Chunks);
                 });
}

void BytesOutputStyle::dumpModuleC13() {
  printHeader(P, "Debug Chunks");

  AutoIndent Indent(P);

  iterateModules(
      File, P, 2,
      [this](uint32_t Modi, const ModuleDebugStreamRef &Stream,
             const MSFStreamLayout &Layout) {
        auto Chunks = Stream.getC13LinesSubstream();
        if (opts::bytes::SplitChunks) {
          for (const auto &SS : Stream.subsections()) {
            BinarySubstreamRef ThisChunk;
            std::tie(ThisChunk, Chunks) = Chunks.split(SS.getRecordLength());
            P.formatMsfStreamData(formatChunkKind(SS.kind()), File, Layout,
                                  ThisChunk);
          }
        } else {
          P.formatMsfStreamData("Debug Chunks", File, Layout, Chunks);
        }
      });
}

void BytesOutputStyle::dumpByteRanges(uint32_t Min, uint32_t Max) {
  printHeader(P, "MSF Bytes");

  AutoIndent Indent(P);

  BinaryStreamReader Reader(File.getMsfBuffer());
  ArrayRef<uint8_t> Data;
  consumeError(Reader.skip(Min));
  uint32_t Size = Max - Min + 1;
  auto EC = Reader.readBytes(Data, Size);
  assert(!EC);
  consumeError(std::move(EC));
  P.formatBinary("Bytes", Data, Min);
}

Expected<codeview::LazyRandomTypeCollection &>
BytesOutputStyle::initializeTypes(uint32_t StreamIdx) {
  auto &TypeCollection = (StreamIdx == StreamTPI) ? TpiTypes : IpiTypes;
  if (TypeCollection)
    return *TypeCollection;

  auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
                                      : File.getPDBIpiStream();
  if (!Tpi)
    return Tpi.takeError();

  auto &Types = Tpi->typeArray();
  uint32_t Count = Tpi->getNumTypeRecords();
  auto Offsets = Tpi->getTypeIndexOffsets();
  TypeCollection =
      std::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets);

  return *TypeCollection;
}

void BytesOutputStyle::dumpFpm() {
  printHeader(P, "Free Page Map");

  msf::MSFStreamLayout FpmLayout = File.getFpmStreamLayout();
  P.formatMsfStreamBlocks(File, FpmLayout);
}

void BytesOutputStyle::dumpStreamBytes() {
  if (StreamPurposes.empty())
    discoverStreamPurposes(File, StreamPurposes);

  printHeader(P, "Stream Data");
  ExitOnError Err("Unexpected error reading stream data");

  auto Specs = parseStreamSpecs(P);

  for (const auto &Spec : Specs) {
    AutoIndent Indent(P);
    if (Spec.SI >= StreamPurposes.size()) {
      P.formatLine("Stream {0}: Not present", Spec.SI);
      continue;
    }
    P.formatMsfStreamData("Data", File, Spec.SI,
                          StreamPurposes[Spec.SI].getShortName(), Spec.Begin,
                          Spec.Size);
  }
}
