//===- MinidumpYAML.cpp - Minidump YAMLIO implementation ------------------===//
//
// 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/ObjectYAML/MinidumpYAML.h"
#include "llvm/Support/Allocator.h"

using namespace llvm;
using namespace llvm::MinidumpYAML;
using namespace llvm::minidump;

/// Perform an optional yaml-mapping of an endian-aware type EndianType. The
/// only purpose of this function is to avoid casting the Default value to the
/// endian type;
template <typename EndianType>
static inline void mapOptional(yaml::IO &IO, const char *Key, EndianType &Val,
                               typename EndianType::value_type Default) {
  IO.mapOptional(Key, Val, EndianType(Default));
}

/// Yaml-map an endian-aware type EndianType as some other type MapType.
template <typename MapType, typename EndianType>
static inline void mapRequiredAs(yaml::IO &IO, const char *Key,
                                 EndianType &Val) {
  MapType Mapped = static_cast<typename EndianType::value_type>(Val);
  IO.mapRequired(Key, Mapped);
  Val = static_cast<typename EndianType::value_type>(Mapped);
}

/// Perform an optional yaml-mapping of an endian-aware type EndianType as some
/// other type MapType.
template <typename MapType, typename EndianType>
static inline void mapOptionalAs(yaml::IO &IO, const char *Key, EndianType &Val,
                                 MapType Default) {
  MapType Mapped = static_cast<typename EndianType::value_type>(Val);
  IO.mapOptional(Key, Mapped, Default);
  Val = static_cast<typename EndianType::value_type>(Mapped);
}

namespace {
/// Return the appropriate yaml Hex type for a given endian-aware type.
template <typename EndianType> struct HexType;
template <> struct HexType<support::ulittle16_t> { using type = yaml::Hex16; };
template <> struct HexType<support::ulittle32_t> { using type = yaml::Hex32; };
template <> struct HexType<support::ulittle64_t> { using type = yaml::Hex64; };
} // namespace

/// Yaml-map an endian-aware type as an appropriately-sized hex value.
template <typename EndianType>
static inline void mapRequiredHex(yaml::IO &IO, const char *Key,
                                  EndianType &Val) {
  mapRequiredAs<typename HexType<EndianType>::type>(IO, Key, Val);
}

/// Perform an optional yaml-mapping of an endian-aware type as an
/// appropriately-sized hex value.
template <typename EndianType>
static inline void mapOptionalHex(yaml::IO &IO, const char *Key,
                                  EndianType &Val,
                                  typename EndianType::value_type Default) {
  mapOptionalAs<typename HexType<EndianType>::type>(IO, Key, Val, Default);
}

Stream::~Stream() = default;

Stream::StreamKind Stream::getKind(StreamType Type) {
  switch (Type) {
  case StreamType::MemoryInfoList:
    return StreamKind::MemoryInfoList;
  case StreamType::MemoryList:
    return StreamKind::MemoryList;
  case StreamType::ModuleList:
    return StreamKind::ModuleList;
  case StreamType::SystemInfo:
    return StreamKind::SystemInfo;
  case StreamType::LinuxCPUInfo:
  case StreamType::LinuxProcStatus:
  case StreamType::LinuxLSBRelease:
  case StreamType::LinuxCMDLine:
  case StreamType::LinuxMaps:
  case StreamType::LinuxProcStat:
  case StreamType::LinuxProcUptime:
    return StreamKind::TextContent;
  case StreamType::ThreadList:
    return StreamKind::ThreadList;
  default:
    return StreamKind::RawContent;
  }
}

std::unique_ptr<Stream> Stream::create(StreamType Type) {
  StreamKind Kind = getKind(Type);
  switch (Kind) {
  case StreamKind::MemoryInfoList:
    return std::make_unique<MemoryInfoListStream>();
  case StreamKind::MemoryList:
    return std::make_unique<MemoryListStream>();
  case StreamKind::ModuleList:
    return std::make_unique<ModuleListStream>();
  case StreamKind::RawContent:
    return std::make_unique<RawContentStream>(Type);
  case StreamKind::SystemInfo:
    return std::make_unique<SystemInfoStream>();
  case StreamKind::TextContent:
    return std::make_unique<TextContentStream>(Type);
  case StreamKind::ThreadList:
    return std::make_unique<ThreadListStream>();
  }
  llvm_unreachable("Unhandled stream kind!");
}

void yaml::ScalarBitSetTraits<MemoryProtection>::bitset(
    IO &IO, MemoryProtection &Protect) {
#define HANDLE_MDMP_PROTECT(CODE, NAME, NATIVENAME)                            \
  IO.bitSetCase(Protect, #NATIVENAME, MemoryProtection::NAME);
#include "llvm/BinaryFormat/MinidumpConstants.def"
}

void yaml::ScalarBitSetTraits<MemoryState>::bitset(IO &IO, MemoryState &State) {
#define HANDLE_MDMP_MEMSTATE(CODE, NAME, NATIVENAME)                           \
  IO.bitSetCase(State, #NATIVENAME, MemoryState::NAME);
#include "llvm/BinaryFormat/MinidumpConstants.def"
}

void yaml::ScalarBitSetTraits<MemoryType>::bitset(IO &IO, MemoryType &Type) {
#define HANDLE_MDMP_MEMTYPE(CODE, NAME, NATIVENAME)                            \
  IO.bitSetCase(Type, #NATIVENAME, MemoryType::NAME);
#include "llvm/BinaryFormat/MinidumpConstants.def"
}

void yaml::ScalarEnumerationTraits<ProcessorArchitecture>::enumeration(
    IO &IO, ProcessorArchitecture &Arch) {
#define HANDLE_MDMP_ARCH(CODE, NAME)                                           \
  IO.enumCase(Arch, #NAME, ProcessorArchitecture::NAME);
#include "llvm/BinaryFormat/MinidumpConstants.def"
  IO.enumFallback<Hex16>(Arch);
}

void yaml::ScalarEnumerationTraits<OSPlatform>::enumeration(IO &IO,
                                                            OSPlatform &Plat) {
#define HANDLE_MDMP_PLATFORM(CODE, NAME)                                       \
  IO.enumCase(Plat, #NAME, OSPlatform::NAME);
#include "llvm/BinaryFormat/MinidumpConstants.def"
  IO.enumFallback<Hex32>(Plat);
}

void yaml::ScalarEnumerationTraits<StreamType>::enumeration(IO &IO,
                                                            StreamType &Type) {
#define HANDLE_MDMP_STREAM_TYPE(CODE, NAME)                                    \
  IO.enumCase(Type, #NAME, StreamType::NAME);
#include "llvm/BinaryFormat/MinidumpConstants.def"
  IO.enumFallback<Hex32>(Type);
}

void yaml::MappingTraits<CPUInfo::ArmInfo>::mapping(IO &IO,
                                                    CPUInfo::ArmInfo &Info) {
  mapRequiredHex(IO, "CPUID", Info.CPUID);
  mapOptionalHex(IO, "ELF hwcaps", Info.ElfHWCaps, 0);
}

namespace {
template <std::size_t N> struct FixedSizeHex {
  FixedSizeHex(uint8_t (&Storage)[N]) : Storage(Storage) {}

  uint8_t (&Storage)[N];
};
} // namespace

namespace llvm {
namespace yaml {
template <std::size_t N> struct ScalarTraits<FixedSizeHex<N>> {
  static void output(const FixedSizeHex<N> &Fixed, void *, raw_ostream &OS) {
    OS << toHex(makeArrayRef(Fixed.Storage));
  }

  static StringRef input(StringRef Scalar, void *, FixedSizeHex<N> &Fixed) {
    if (!all_of(Scalar, isHexDigit))
      return "Invalid hex digit in input";
    if (Scalar.size() < 2 * N)
      return "String too short";
    if (Scalar.size() > 2 * N)
      return "String too long";
    copy(fromHex(Scalar), Fixed.Storage);
    return "";
  }

  static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
};
} // namespace yaml
} // namespace llvm
void yaml::MappingTraits<CPUInfo::OtherInfo>::mapping(
    IO &IO, CPUInfo::OtherInfo &Info) {
  FixedSizeHex<sizeof(Info.ProcessorFeatures)> Features(Info.ProcessorFeatures);
  IO.mapRequired("Features", Features);
}

namespace {
/// A type which only accepts strings of a fixed size for yaml conversion.
template <std::size_t N> struct FixedSizeString {
  FixedSizeString(char (&Storage)[N]) : Storage(Storage) {}

  char (&Storage)[N];
};
} // namespace

namespace llvm {
namespace yaml {
template <std::size_t N> struct ScalarTraits<FixedSizeString<N>> {
  static void output(const FixedSizeString<N> &Fixed, void *, raw_ostream &OS) {
    OS << StringRef(Fixed.Storage, N);
  }

  static StringRef input(StringRef Scalar, void *, FixedSizeString<N> &Fixed) {
    if (Scalar.size() < N)
      return "String too short";
    if (Scalar.size() > N)
      return "String too long";
    copy(Scalar, Fixed.Storage);
    return "";
  }

  static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
};
} // namespace yaml
} // namespace llvm

void yaml::MappingTraits<CPUInfo::X86Info>::mapping(IO &IO,
                                                    CPUInfo::X86Info &Info) {
  FixedSizeString<sizeof(Info.VendorID)> VendorID(Info.VendorID);
  IO.mapRequired("Vendor ID", VendorID);

  mapRequiredHex(IO, "Version Info", Info.VersionInfo);
  mapRequiredHex(IO, "Feature Info", Info.FeatureInfo);
  mapOptionalHex(IO, "AMD Extended Features", Info.AMDExtendedFeatures, 0);
}

void yaml::MappingTraits<MemoryInfo>::mapping(IO &IO, MemoryInfo &Info) {
  mapRequiredHex(IO, "Base Address", Info.BaseAddress);
  mapOptionalHex(IO, "Allocation Base", Info.AllocationBase, Info.BaseAddress);
  mapRequiredAs<MemoryProtection>(IO, "Allocation Protect",
                                  Info.AllocationProtect);
  mapOptionalHex(IO, "Reserved0", Info.Reserved0, 0);
  mapRequiredHex(IO, "Region Size", Info.RegionSize);
  mapRequiredAs<MemoryState>(IO, "State", Info.State);
  mapOptionalAs<MemoryProtection>(IO, "Protect", Info.Protect,
                                  Info.AllocationProtect);
  mapRequiredAs<MemoryType>(IO, "Type", Info.Type);
  mapOptionalHex(IO, "Reserved1", Info.Reserved1, 0);
}

void yaml::MappingTraits<VSFixedFileInfo>::mapping(IO &IO,
                                                   VSFixedFileInfo &Info) {
  mapOptionalHex(IO, "Signature", Info.Signature, 0);
  mapOptionalHex(IO, "Struct Version", Info.StructVersion, 0);
  mapOptionalHex(IO, "File Version High", Info.FileVersionHigh, 0);
  mapOptionalHex(IO, "File Version Low", Info.FileVersionLow, 0);
  mapOptionalHex(IO, "Product Version High", Info.ProductVersionHigh, 0);
  mapOptionalHex(IO, "Product Version Low", Info.ProductVersionLow, 0);
  mapOptionalHex(IO, "File Flags Mask", Info.FileFlagsMask, 0);
  mapOptionalHex(IO, "File Flags", Info.FileFlags, 0);
  mapOptionalHex(IO, "File OS", Info.FileOS, 0);
  mapOptionalHex(IO, "File Type", Info.FileType, 0);
  mapOptionalHex(IO, "File Subtype", Info.FileSubtype, 0);
  mapOptionalHex(IO, "File Date High", Info.FileDateHigh, 0);
  mapOptionalHex(IO, "File Date Low", Info.FileDateLow, 0);
}

void yaml::MappingTraits<ModuleListStream::entry_type>::mapping(
    IO &IO, ModuleListStream::entry_type &M) {
  mapRequiredHex(IO, "Base of Image", M.Entry.BaseOfImage);
  mapRequiredHex(IO, "Size of Image", M.Entry.SizeOfImage);
  mapOptionalHex(IO, "Checksum", M.Entry.Checksum, 0);
  IO.mapOptional("Time Date Stamp", M.Entry.TimeDateStamp,
                 support::ulittle32_t(0));
  IO.mapRequired("Module Name", M.Name);
  IO.mapOptional("Version Info", M.Entry.VersionInfo, VSFixedFileInfo());
  IO.mapRequired("CodeView Record", M.CvRecord);
  IO.mapOptional("Misc Record", M.MiscRecord, yaml::BinaryRef());
  mapOptionalHex(IO, "Reserved0", M.Entry.Reserved0, 0);
  mapOptionalHex(IO, "Reserved1", M.Entry.Reserved1, 0);
}

static void streamMapping(yaml::IO &IO, RawContentStream &Stream) {
  IO.mapOptional("Content", Stream.Content);
  IO.mapOptional("Size", Stream.Size, Stream.Content.binary_size());
}

static StringRef streamValidate(RawContentStream &Stream) {
  if (Stream.Size.value < Stream.Content.binary_size())
    return "Stream size must be greater or equal to the content size";
  return "";
}

void yaml::MappingTraits<MemoryListStream::entry_type>::mapping(
    IO &IO, MemoryListStream::entry_type &Range) {
  MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
      IO, Range.Entry, Range.Content);
}

static void streamMapping(yaml::IO &IO, MemoryInfoListStream &Stream) {
  IO.mapRequired("Memory Ranges", Stream.Infos);
}

static void streamMapping(yaml::IO &IO, MemoryListStream &Stream) {
  IO.mapRequired("Memory Ranges", Stream.Entries);
}

static void streamMapping(yaml::IO &IO, ModuleListStream &Stream) {
  IO.mapRequired("Modules", Stream.Entries);
}

static void streamMapping(yaml::IO &IO, SystemInfoStream &Stream) {
  SystemInfo &Info = Stream.Info;
  IO.mapRequired("Processor Arch", Info.ProcessorArch);
  mapOptional(IO, "Processor Level", Info.ProcessorLevel, 0);
  mapOptional(IO, "Processor Revision", Info.ProcessorRevision, 0);
  IO.mapOptional("Number of Processors", Info.NumberOfProcessors, 0);
  IO.mapOptional("Product type", Info.ProductType, 0);
  mapOptional(IO, "Major Version", Info.MajorVersion, 0);
  mapOptional(IO, "Minor Version", Info.MinorVersion, 0);
  mapOptional(IO, "Build Number", Info.BuildNumber, 0);
  IO.mapRequired("Platform ID", Info.PlatformId);
  IO.mapOptional("CSD Version", Stream.CSDVersion, "");
  mapOptionalHex(IO, "Suite Mask", Info.SuiteMask, 0);
  mapOptionalHex(IO, "Reserved", Info.Reserved, 0);
  switch (static_cast<ProcessorArchitecture>(Info.ProcessorArch)) {
  case ProcessorArchitecture::X86:
  case ProcessorArchitecture::AMD64:
    IO.mapOptional("CPU", Info.CPU.X86);
    break;
  case ProcessorArchitecture::ARM:
  case ProcessorArchitecture::ARM64:
    IO.mapOptional("CPU", Info.CPU.Arm);
    break;
  default:
    IO.mapOptional("CPU", Info.CPU.Other);
    break;
  }
}

static void streamMapping(yaml::IO &IO, TextContentStream &Stream) {
  IO.mapOptional("Text", Stream.Text);
}

void yaml::MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
    IO &IO, MemoryDescriptor &Memory, BinaryRef &Content) {
  mapRequiredHex(IO, "Start of Memory Range", Memory.StartOfMemoryRange);
  IO.mapRequired("Content", Content);
}

void yaml::MappingTraits<ThreadListStream::entry_type>::mapping(
    IO &IO, ThreadListStream::entry_type &T) {
  mapRequiredHex(IO, "Thread Id", T.Entry.ThreadId);
  mapOptionalHex(IO, "Suspend Count", T.Entry.SuspendCount, 0);
  mapOptionalHex(IO, "Priority Class", T.Entry.PriorityClass, 0);
  mapOptionalHex(IO, "Priority", T.Entry.Priority, 0);
  mapOptionalHex(IO, "Environment Block", T.Entry.EnvironmentBlock, 0);
  IO.mapRequired("Context", T.Context);
  IO.mapRequired("Stack", T.Entry.Stack, T.Stack);
}

static void streamMapping(yaml::IO &IO, ThreadListStream &Stream) {
  IO.mapRequired("Threads", Stream.Entries);
}

void yaml::MappingTraits<std::unique_ptr<Stream>>::mapping(
    yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
  StreamType Type;
  if (IO.outputting())
    Type = S->Type;
  IO.mapRequired("Type", Type);

  if (!IO.outputting())
    S = MinidumpYAML::Stream::create(Type);
  switch (S->Kind) {
  case MinidumpYAML::Stream::StreamKind::MemoryInfoList:
    streamMapping(IO, llvm::cast<MemoryInfoListStream>(*S));
    break;
  case MinidumpYAML::Stream::StreamKind::MemoryList:
    streamMapping(IO, llvm::cast<MemoryListStream>(*S));
    break;
  case MinidumpYAML::Stream::StreamKind::ModuleList:
    streamMapping(IO, llvm::cast<ModuleListStream>(*S));
    break;
  case MinidumpYAML::Stream::StreamKind::RawContent:
    streamMapping(IO, llvm::cast<RawContentStream>(*S));
    break;
  case MinidumpYAML::Stream::StreamKind::SystemInfo:
    streamMapping(IO, llvm::cast<SystemInfoStream>(*S));
    break;
  case MinidumpYAML::Stream::StreamKind::TextContent:
    streamMapping(IO, llvm::cast<TextContentStream>(*S));
    break;
  case MinidumpYAML::Stream::StreamKind::ThreadList:
    streamMapping(IO, llvm::cast<ThreadListStream>(*S));
    break;
  }
}

StringRef yaml::MappingTraits<std::unique_ptr<Stream>>::validate(
    yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
  switch (S->Kind) {
  case MinidumpYAML::Stream::StreamKind::RawContent:
    return streamValidate(cast<RawContentStream>(*S));
  case MinidumpYAML::Stream::StreamKind::MemoryInfoList:
  case MinidumpYAML::Stream::StreamKind::MemoryList:
  case MinidumpYAML::Stream::StreamKind::ModuleList:
  case MinidumpYAML::Stream::StreamKind::SystemInfo:
  case MinidumpYAML::Stream::StreamKind::TextContent:
  case MinidumpYAML::Stream::StreamKind::ThreadList:
    return "";
  }
  llvm_unreachable("Fully covered switch above!");
}

void yaml::MappingTraits<Object>::mapping(IO &IO, Object &O) {
  IO.mapTag("!minidump", true);
  mapOptionalHex(IO, "Signature", O.Header.Signature, Header::MagicSignature);
  mapOptionalHex(IO, "Version", O.Header.Version, Header::MagicVersion);
  mapOptionalHex(IO, "Flags", O.Header.Flags, 0);
  IO.mapRequired("Streams", O.Streams);
}

Expected<std::unique_ptr<Stream>>
Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
  StreamKind Kind = getKind(StreamDesc.Type);
  switch (Kind) {
  case StreamKind::MemoryInfoList: {
    if (auto ExpectedList = File.getMemoryInfoList())
      return std::make_unique<MemoryInfoListStream>(*ExpectedList);
    else
      return ExpectedList.takeError();
  }
  case StreamKind::MemoryList: {
    auto ExpectedList = File.getMemoryList();
    if (!ExpectedList)
      return ExpectedList.takeError();
    std::vector<MemoryListStream::entry_type> Ranges;
    for (const MemoryDescriptor &MD : *ExpectedList) {
      auto ExpectedContent = File.getRawData(MD.Memory);
      if (!ExpectedContent)
        return ExpectedContent.takeError();
      Ranges.push_back({MD, *ExpectedContent});
    }
    return std::make_unique<MemoryListStream>(std::move(Ranges));
  }
  case StreamKind::ModuleList: {
    auto ExpectedList = File.getModuleList();
    if (!ExpectedList)
      return ExpectedList.takeError();
    std::vector<ModuleListStream::entry_type> Modules;
    for (const Module &M : *ExpectedList) {
      auto ExpectedName = File.getString(M.ModuleNameRVA);
      if (!ExpectedName)
        return ExpectedName.takeError();
      auto ExpectedCv = File.getRawData(M.CvRecord);
      if (!ExpectedCv)
        return ExpectedCv.takeError();
      auto ExpectedMisc = File.getRawData(M.MiscRecord);
      if (!ExpectedMisc)
        return ExpectedMisc.takeError();
      Modules.push_back(
          {M, std::move(*ExpectedName), *ExpectedCv, *ExpectedMisc});
    }
    return std::make_unique<ModuleListStream>(std::move(Modules));
  }
  case StreamKind::RawContent:
    return std::make_unique<RawContentStream>(StreamDesc.Type,
                                               File.getRawStream(StreamDesc));
  case StreamKind::SystemInfo: {
    auto ExpectedInfo = File.getSystemInfo();
    if (!ExpectedInfo)
      return ExpectedInfo.takeError();
    auto ExpectedCSDVersion = File.getString(ExpectedInfo->CSDVersionRVA);
    if (!ExpectedCSDVersion)
      return ExpectedInfo.takeError();
    return std::make_unique<SystemInfoStream>(*ExpectedInfo,
                                               std::move(*ExpectedCSDVersion));
  }
  case StreamKind::TextContent:
    return std::make_unique<TextContentStream>(
        StreamDesc.Type, toStringRef(File.getRawStream(StreamDesc)));
  case StreamKind::ThreadList: {
    auto ExpectedList = File.getThreadList();
    if (!ExpectedList)
      return ExpectedList.takeError();
    std::vector<ThreadListStream::entry_type> Threads;
    for (const Thread &T : *ExpectedList) {
      auto ExpectedStack = File.getRawData(T.Stack.Memory);
      if (!ExpectedStack)
        return ExpectedStack.takeError();
      auto ExpectedContext = File.getRawData(T.Context);
      if (!ExpectedContext)
        return ExpectedContext.takeError();
      Threads.push_back({T, *ExpectedStack, *ExpectedContext});
    }
    return std::make_unique<ThreadListStream>(std::move(Threads));
  }
  }
  llvm_unreachable("Unhandled stream kind!");
}

Expected<Object> Object::create(const object::MinidumpFile &File) {
  std::vector<std::unique_ptr<Stream>> Streams;
  Streams.reserve(File.streams().size());
  for (const Directory &StreamDesc : File.streams()) {
    auto ExpectedStream = Stream::create(StreamDesc, File);
    if (!ExpectedStream)
      return ExpectedStream.takeError();
    Streams.push_back(std::move(*ExpectedStream));
  }
  return Object(File.header(), std::move(Streams));
}
