//===- YAMLOutputStyle.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 "YAMLOutputStyle.h"

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

#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.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/PublicsStream.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"

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

static bool checkModuleSubsection(opts::ModuleSubsection MS) {
  return any_of(opts::pdb2yaml::DumpModuleSubsections,
                [=](opts::ModuleSubsection M) {
                  return M == MS || M == opts::ModuleSubsection::All;
                });
}

YAMLOutputStyle::YAMLOutputStyle(PDBFile &File)
    : File(File), Out(outs()), Obj(File.getAllocator()) {
  Out.setWriteDefaultValues(!opts::pdb2yaml::Minimal);
}

Error YAMLOutputStyle::dump() {
  if (opts::pdb2yaml::StreamDirectory)
    opts::pdb2yaml::StreamMetadata = true;

  if (auto EC = dumpFileHeaders())
    return EC;

  if (auto EC = dumpStreamMetadata())
    return EC;

  if (auto EC = dumpStreamDirectory())
    return EC;

  if (auto EC = dumpStringTable())
    return EC;

  if (auto EC = dumpPDBStream())
    return EC;

  if (auto EC = dumpDbiStream())
    return EC;

  if (auto EC = dumpTpiStream())
    return EC;

  if (auto EC = dumpIpiStream())
    return EC;

  if (auto EC = dumpPublics())
    return EC;

  flush();
  return Error::success();
}


Error YAMLOutputStyle::dumpFileHeaders() {
  if (opts::pdb2yaml::NoFileHeaders)
    return Error::success();

  yaml::MSFHeaders Headers;
  Obj.Headers.emplace();
  Obj.Headers->SuperBlock.NumBlocks = File.getBlockCount();
  Obj.Headers->SuperBlock.BlockMapAddr = File.getBlockMapIndex();
  Obj.Headers->SuperBlock.BlockSize = File.getBlockSize();
  auto Blocks = File.getDirectoryBlockArray();
  Obj.Headers->DirectoryBlocks.assign(Blocks.begin(), Blocks.end());
  Obj.Headers->NumDirectoryBlocks = File.getNumDirectoryBlocks();
  Obj.Headers->SuperBlock.NumDirectoryBytes = File.getNumDirectoryBytes();
  Obj.Headers->NumStreams =
      opts::pdb2yaml::StreamMetadata ? File.getNumStreams() : 0;
  Obj.Headers->SuperBlock.FreeBlockMapBlock = File.getFreeBlockMapBlock();
  Obj.Headers->SuperBlock.Unknown1 = File.getUnknown1();
  Obj.Headers->FileSize = File.getFileSize();

  return Error::success();
}

Error YAMLOutputStyle::dumpStringTable() {
  bool RequiresStringTable = opts::pdb2yaml::DumpModuleFiles ||
                             !opts::pdb2yaml::DumpModuleSubsections.empty();
  bool RequestedStringTable = opts::pdb2yaml::StringTable;
  if (!RequiresStringTable && !RequestedStringTable)
    return Error::success();

  auto ExpectedST = File.getStringTable();
  if (!ExpectedST)
    return ExpectedST.takeError();

  Obj.StringTable.emplace();
  const auto &ST = ExpectedST.get();
  for (auto ID : ST.name_ids()) {
    auto S = ST.getStringForID(ID);
    if (!S)
      return S.takeError();
    if (S->empty())
      continue;
    Obj.StringTable->push_back(*S);
  }
  return Error::success();
}

Error YAMLOutputStyle::dumpStreamMetadata() {
  if (!opts::pdb2yaml::StreamMetadata)
    return Error::success();

  Obj.StreamSizes.emplace();
  Obj.StreamSizes->assign(File.getStreamSizes().begin(),
                          File.getStreamSizes().end());
  return Error::success();
}

Error YAMLOutputStyle::dumpStreamDirectory() {
  if (!opts::pdb2yaml::StreamDirectory)
    return Error::success();

  auto StreamMap = File.getStreamMap();
  Obj.StreamMap.emplace();
  for (auto &Stream : StreamMap) {
    pdb::yaml::StreamBlockList BlockList;
    BlockList.Blocks.assign(Stream.begin(), Stream.end());
    Obj.StreamMap->push_back(BlockList);
  }

  return Error::success();
}

Error YAMLOutputStyle::dumpPDBStream() {
  if (!opts::pdb2yaml::PdbStream)
    return Error::success();

  auto IS = File.getPDBInfoStream();
  if (!IS)
    return IS.takeError();

  auto &InfoS = IS.get();
  Obj.PdbStream.emplace();
  Obj.PdbStream->Age = InfoS.getAge();
  Obj.PdbStream->Guid = InfoS.getGuid();
  Obj.PdbStream->Signature = InfoS.getSignature();
  Obj.PdbStream->Version = InfoS.getVersion();
  Obj.PdbStream->Features = InfoS.getFeatureSignatures();

  return Error::success();
}

static opts::ModuleSubsection convertSubsectionKind(DebugSubsectionKind K) {
  switch (K) {
  case DebugSubsectionKind::CrossScopeExports:
    return opts::ModuleSubsection::CrossScopeExports;
  case DebugSubsectionKind::CrossScopeImports:
    return opts::ModuleSubsection::CrossScopeImports;
  case DebugSubsectionKind::FileChecksums:
    return opts::ModuleSubsection::FileChecksums;
  case DebugSubsectionKind::InlineeLines:
    return opts::ModuleSubsection::InlineeLines;
  case DebugSubsectionKind::Lines:
    return opts::ModuleSubsection::Lines;
  case DebugSubsectionKind::Symbols:
    return opts::ModuleSubsection::Symbols;
  case DebugSubsectionKind::StringTable:
    return opts::ModuleSubsection::StringTable;
  case DebugSubsectionKind::FrameData:
    return opts::ModuleSubsection::FrameData;
  default:
    return opts::ModuleSubsection::Unknown;
  }
  llvm_unreachable("Unreachable!");
}

Error YAMLOutputStyle::dumpDbiStream() {
  if (!opts::pdb2yaml::DbiStream)
    return Error::success();

  if (!File.hasPDBDbiStream())
    return Error::success();

  auto DbiS = File.getPDBDbiStream();
  if (!DbiS)
    return DbiS.takeError();

  auto &DS = DbiS.get();
  Obj.DbiStream.emplace();
  Obj.DbiStream->Age = DS.getAge();
  Obj.DbiStream->BuildNumber = DS.getBuildNumber();
  Obj.DbiStream->Flags = DS.getFlags();
  Obj.DbiStream->MachineType = DS.getMachineType();
  Obj.DbiStream->PdbDllRbld = DS.getPdbDllRbld();
  Obj.DbiStream->PdbDllVersion = DS.getPdbDllVersion();
  Obj.DbiStream->VerHeader = DS.getDbiVersion();
  if (opts::pdb2yaml::DumpModules) {
    const auto &Modules = DS.modules();
    for (uint32_t I = 0; I < Modules.getModuleCount(); ++I) {
      DbiModuleDescriptor MI = Modules.getModuleDescriptor(I);

      Obj.DbiStream->ModInfos.emplace_back();
      yaml::PdbDbiModuleInfo &DMI = Obj.DbiStream->ModInfos.back();

      DMI.Mod = MI.getModuleName();
      DMI.Obj = MI.getObjFileName();
      if (opts::pdb2yaml::DumpModuleFiles) {
        auto Files = Modules.source_files(I);
        DMI.SourceFiles.assign(Files.begin(), Files.end());
      }

      uint16_t ModiStream = MI.getModuleStreamIndex();
      if (ModiStream == kInvalidStreamIndex)
        continue;

      auto ModStreamData = File.createIndexedStream(ModiStream);
      pdb::ModuleDebugStreamRef ModS(MI, std::move(ModStreamData));
      if (auto EC = ModS.reload())
        return EC;

      auto ExpectedST = File.getStringTable();
      if (!ExpectedST)
        return ExpectedST.takeError();
      if (!opts::pdb2yaml::DumpModuleSubsections.empty() &&
          ModS.hasDebugSubsections()) {
        auto ExpectedChecksums = ModS.findChecksumsSubsection();
        if (!ExpectedChecksums)
          return ExpectedChecksums.takeError();

        StringsAndChecksumsRef SC(ExpectedST->getStringTable(),
                                  *ExpectedChecksums);

        for (const auto &SS : ModS.subsections()) {
          opts::ModuleSubsection OptionKind = convertSubsectionKind(SS.kind());
          if (!checkModuleSubsection(OptionKind))
            continue;

          auto Converted =
              CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection(SC, SS);
          if (!Converted)
            return Converted.takeError();
          DMI.Subsections.push_back(*Converted);
        }
      }

      if (opts::pdb2yaml::DumpModuleSyms) {
        DMI.Modi.emplace();

        DMI.Modi->Signature = ModS.signature();
        bool HadError = false;
        for (auto &Sym : ModS.symbols(&HadError)) {
          auto ES = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(Sym);
          if (!ES)
            return ES.takeError();

          DMI.Modi->Symbols.push_back(*ES);
        }
      }
    }
  }
  return Error::success();
}

Error YAMLOutputStyle::dumpTpiStream() {
  if (!opts::pdb2yaml::TpiStream)
    return Error::success();

  auto TpiS = File.getPDBTpiStream();
  if (!TpiS)
    return TpiS.takeError();

  auto &TS = TpiS.get();
  Obj.TpiStream.emplace();
  Obj.TpiStream->Version = TS.getTpiVersion();
  for (auto &Record : TS.types(nullptr)) {
    auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record);
    if (!ExpectedRecord)
      return ExpectedRecord.takeError();
    Obj.TpiStream->Records.push_back(*ExpectedRecord);
  }

  return Error::success();
}

Error YAMLOutputStyle::dumpIpiStream() {
  if (!opts::pdb2yaml::IpiStream)
    return Error::success();

  auto InfoS = File.getPDBInfoStream();
  if (!InfoS)
    return InfoS.takeError();
  if (!InfoS->containsIdStream())
    return Error::success();

  auto IpiS = File.getPDBIpiStream();
  if (!IpiS)
    return IpiS.takeError();

  auto &IS = IpiS.get();
  Obj.IpiStream.emplace();
  Obj.IpiStream->Version = IS.getTpiVersion();
  for (auto &Record : IS.types(nullptr)) {
    auto ExpectedRecord = CodeViewYAML::LeafRecord::fromCodeViewRecord(Record);
    if (!ExpectedRecord)
      return ExpectedRecord.takeError();

    Obj.IpiStream->Records.push_back(*ExpectedRecord);
  }

  return Error::success();
}

Error YAMLOutputStyle::dumpPublics() {
  if (!opts::pdb2yaml::PublicsStream)
    return Error::success();

  Obj.PublicsStream.emplace();
  auto ExpectedPublics = File.getPDBPublicsStream();
  if (!ExpectedPublics) {
    llvm::consumeError(ExpectedPublics.takeError());
    return Error::success();
  }

  PublicsStream &Publics = *ExpectedPublics;
  const GSIHashTable &PublicsTable = Publics.getPublicsTable();

  auto ExpectedSyms = File.getPDBSymbolStream();
  if (!ExpectedSyms) {
    llvm::consumeError(ExpectedSyms.takeError());
    return Error::success();
  }

  BinaryStreamRef SymStream =
      ExpectedSyms->getSymbolArray().getUnderlyingStream();
  for (uint32_t PubSymOff : PublicsTable) {
    Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, PubSymOff);
    if (!Sym)
      return Sym.takeError();
    auto ES = CodeViewYAML::SymbolRecord::fromCodeViewSymbol(*Sym);
    if (!ES)
      return ES.takeError();

    Obj.PublicsStream->PubSyms.push_back(*ES);
  }

  return Error::success();
}

void YAMLOutputStyle::flush() {
  Out << Obj;
  outs().flush();
}
