//===- InputFile.h -------------------------------------------- *- 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H
#define LLVM_DEBUGINFO_PDB_NATIVE_INPUTFILE_H

#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/iterator.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Error.h"

namespace llvm {
namespace codeview {
class LazyRandomTypeCollection;
}
namespace object {
class COFFObjectFile;
} // namespace object

namespace pdb {
class InputFile;
class LinePrinter;
class PDBFile;
class NativeSession;
class SymbolGroupIterator;
class SymbolGroup;

class InputFile {
  InputFile();

  std::unique_ptr<NativeSession> PdbSession;
  object::OwningBinary<object::Binary> CoffObject;
  std::unique_ptr<MemoryBuffer> UnknownFile;
  PointerUnion<PDBFile *, object::COFFObjectFile *, MemoryBuffer *> PdbOrObj;

  using TypeCollectionPtr = std::unique_ptr<codeview::LazyRandomTypeCollection>;

  TypeCollectionPtr Types;
  TypeCollectionPtr Ids;

  enum TypeCollectionKind { kTypes, kIds };
  codeview::LazyRandomTypeCollection &
  getOrCreateTypeCollection(TypeCollectionKind Kind);

public:
  InputFile(PDBFile *Pdb) { PdbOrObj = Pdb; }
  InputFile(object::COFFObjectFile *Obj) { PdbOrObj = Obj; }
  InputFile(MemoryBuffer *Buffer) { PdbOrObj = Buffer; }
  ~InputFile();
  InputFile(InputFile &&Other) = default;

  static Expected<InputFile> open(StringRef Path,
                                  bool AllowUnknownFile = false);

  PDBFile &pdb();
  const PDBFile &pdb() const;
  object::COFFObjectFile &obj();
  const object::COFFObjectFile &obj() const;
  MemoryBuffer &unknown();
  const MemoryBuffer &unknown() const;

  StringRef getFilePath() const;

  bool hasTypes() const;
  bool hasIds() const;

  codeview::LazyRandomTypeCollection &types();
  codeview::LazyRandomTypeCollection &ids();

  iterator_range<SymbolGroupIterator> symbol_groups();
  SymbolGroupIterator symbol_groups_begin();
  SymbolGroupIterator symbol_groups_end();

  bool isPdb() const;
  bool isObj() const;
  bool isUnknown() const;
};

class SymbolGroup {
  friend class SymbolGroupIterator;

public:
  explicit SymbolGroup(InputFile *File, uint32_t GroupIndex = 0);

  Expected<StringRef> getNameFromStringTable(uint32_t Offset) const;
  Expected<StringRef> getNameFromChecksums(uint32_t Offset) const;

  void formatFromFileName(LinePrinter &Printer, StringRef File,
                          bool Append = false) const;

  void formatFromChecksumsOffset(LinePrinter &Printer, uint32_t Offset,
                                 bool Append = false) const;

  StringRef name() const;

  codeview::DebugSubsectionArray getDebugSubsections() const {
    return Subsections;
  }
  const ModuleDebugStreamRef &getPdbModuleStream() const;

  const InputFile &getFile() const { return *File; }
  InputFile &getFile() { return *File; }

  bool hasDebugStream() const { return DebugStream != nullptr; }

private:
  void initializeForPdb(uint32_t Modi);
  void updatePdbModi(uint32_t Modi);
  void updateDebugS(const codeview::DebugSubsectionArray &SS);

  void rebuildChecksumMap();
  InputFile *File = nullptr;
  StringRef Name;
  codeview::DebugSubsectionArray Subsections;
  std::shared_ptr<ModuleDebugStreamRef> DebugStream;
  codeview::StringsAndChecksumsRef SC;
  StringMap<codeview::FileChecksumEntry> ChecksumsByFile;
};

class SymbolGroupIterator
    : public iterator_facade_base<SymbolGroupIterator,
                                  std::forward_iterator_tag, SymbolGroup> {
public:
  SymbolGroupIterator();
  explicit SymbolGroupIterator(InputFile &File);
  SymbolGroupIterator(const SymbolGroupIterator &Other) = default;
  SymbolGroupIterator &operator=(const SymbolGroupIterator &R) = default;

  const SymbolGroup &operator*() const;
  SymbolGroup &operator*();

  bool operator==(const SymbolGroupIterator &R) const;
  SymbolGroupIterator &operator++();

private:
  void scanToNextDebugS();
  bool isEnd() const;

  uint32_t Index = 0;
  Optional<object::section_iterator> SectionIter;
  SymbolGroup Value;
};

Expected<ModuleDebugStreamRef>
getModuleDebugStream(PDBFile &File, StringRef &ModuleName, uint32_t Index);
Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File,
                                                    uint32_t Index);

bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group,
                           const FilterOptions &Filters);

// TODO: Change these callbacks to be function_refs (de-templatify them).
template <typename CallbackT>
Error iterateOneModule(InputFile &File, const PrintScope &HeaderScope,
                       const SymbolGroup &SG, uint32_t Modi,
                       CallbackT Callback) {
  HeaderScope.P.formatLine(
      "Mod {0:4} | `{1}`: ",
      fmt_align(Modi, AlignStyle::Right, HeaderScope.LabelWidth), SG.name());

  AutoIndent Indent(HeaderScope);
  return Callback(Modi, SG);
}

template <typename CallbackT>
Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
                          CallbackT Callback) {
  AutoIndent Indent(HeaderScope);

  FilterOptions Filters = HeaderScope.P.getFilters();
  if (Filters.DumpModi) {
    uint32_t Modi = Filters.DumpModi.getValue();
    SymbolGroup SG(&Input, Modi);
    return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
                            SG, Modi, Callback);
  }

  uint32_t I = 0;

  for (const auto &SG : Input.symbol_groups()) {
    if (shouldDumpSymbolGroup(I, SG, Filters))
      if (auto Err =
              iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)),
                               SG, I, Callback))
        return Err;

    ++I;
  }
  return Error::success();
}

template <typename SubsectionT>
Error iterateModuleSubsections(
    InputFile &File, const PrintScope &HeaderScope,
    llvm::function_ref<Error(uint32_t, const SymbolGroup &, SubsectionT &)>
        Callback) {

  return iterateSymbolGroups(
      File, HeaderScope, [&](uint32_t Modi, const SymbolGroup &SG) -> Error {
        for (const auto &SS : SG.getDebugSubsections()) {
          SubsectionT Subsection;

          if (SS.kind() != Subsection.kind())
            continue;

          BinaryStreamReader Reader(SS.getRecordData());
          if (auto Err = Subsection.initialize(Reader))
            continue;
          if (auto Err = Callback(Modi, SG, Subsection))
            return Err;
        }
        return Error::success();
      });
}

} // namespace pdb
} // namespace llvm

#endif
