//==- 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 {
    auto Name = Strings.getStringForID(Entry.FileNI);
    assert(Name && "InjectedSourceStream should have rejected this");
    return *Name;
  }

  std::string getObjectFileName() const override {
    auto ObjName = Strings.getStringForID(Entry.ObjNI);
    assert(ObjName && "InjectedSourceStream should have rejected this");
    return *ObjName;
  }

  std::string getVirtualFileName() const override {
    auto VName = Strings.getStringForID(Entry.VFileNI);
    assert(VName && "InjectedSourceStream should have rejected this");
    return *VName;
  }

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

  std::string getCode() const override {
    // Get name of stream storing the data.
    auto VName = Strings.getStringForID(Entry.VFileNI);
    assert(VName && "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(); }

}
}
