//==- NativeEnumInjectedSources.cpp - Native Injected Source Enumerator --*-==//
//
// 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 "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"

#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"

namespace llvm {
namespace pdb {

namespace {

Expected<std::string> readStreamData(BinaryStream &Stream, uint32_t Limit) {
  uint32_t Offset = 0, DataLength = std::min(Limit, Stream.getLength());
  std::string Result;
  Result.reserve(DataLength);
  while (Offset < DataLength) {
    ArrayRef<uint8_t> Data;
    if (auto E = Stream.readLongestContiguousChunk(Offset, Data))
      return std::move(E);
    Data = Data.take_front(DataLength - Offset);
    Offset += Data.size();
    Result += toStringRef(Data);
  }
  return Result;
}

class NativeInjectedSource final : public IPDBInjectedSource {
  const SrcHeaderBlockEntry &Entry;
  const PDBStringTable &Strings;
  PDBFile &File;

public:
  NativeInjectedSource(const SrcHeaderBlockEntry &Entry,
                       PDBFile &File, const PDBStringTable &Strings)
      : Entry(Entry), Strings(Strings), File(File) {}

  uint32_t getCrc32() const override { return Entry.CRC; }
  uint64_t getCodeByteSize() const override { return Entry.FileSize; }

  std::string getFileName() const override {
    StringRef Ret = cantFail(Strings.getStringForID(Entry.FileNI),
                             "InjectedSourceStream should have rejected this");
    return Ret;
  }

  std::string getObjectFileName() const override {
    StringRef Ret = cantFail(Strings.getStringForID(Entry.ObjNI),
                             "InjectedSourceStream should have rejected this");
    return Ret;
  }

  std::string getVirtualFileName() const override {
    StringRef Ret = cantFail(Strings.getStringForID(Entry.VFileNI),
                             "InjectedSourceStream should have rejected this");
    return Ret;
  }

  uint32_t getCompression() const override { return Entry.Compression; }

  std::string getCode() const override {
    // Get name of stream storing the data.
    StringRef VName =
        cantFail(Strings.getStringForID(Entry.VFileNI),
                 "InjectedSourceStream should have rejected this");
    std::string StreamName = ("/src/files/" + VName).str();

    // Find stream with that name and read its data.
    // FIXME: Consider validating (or even loading) all this in
    // InjectedSourceStream so that no error can happen here.
    auto ExpectedFileStream = File.safelyCreateNamedStream(StreamName);
    if (!ExpectedFileStream) {
      consumeError(ExpectedFileStream.takeError());
      return "(failed to open data stream)";
    }

    auto Data = readStreamData(**ExpectedFileStream, Entry.FileSize);
    if (!Data) {
      consumeError(Data.takeError());
      return "(failed to read data)";
    }
    return *Data;
  }
};

} // namespace

NativeEnumInjectedSources::NativeEnumInjectedSources(
    PDBFile &File, const InjectedSourceStream &IJS,
    const PDBStringTable &Strings)
    : File(File), Stream(IJS), Strings(Strings), Cur(Stream.begin()) {}

uint32_t NativeEnumInjectedSources::getChildCount() const {
  return static_cast<uint32_t>(Stream.size());
}

std::unique_ptr<IPDBInjectedSource>
NativeEnumInjectedSources::getChildAtIndex(uint32_t N) const {
  if (N >= getChildCount())
    return nullptr;
  return std::make_unique<NativeInjectedSource>(std::next(Stream.begin(), N)->second,
                                           File, Strings);
}

std::unique_ptr<IPDBInjectedSource> NativeEnumInjectedSources::getNext() {
  if (Cur == Stream.end())
    return nullptr;
  return std::make_unique<NativeInjectedSource>((Cur++)->second, File, Strings);
}

void NativeEnumInjectedSources::reset() { Cur = Stream.begin(); }

}
}
