//===- FDRRecordProducer.cpp - XRay FDR Mode Record Producer --------------===//
//
// 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/XRay/FDRRecordProducer.h"
#include "llvm/Support/DataExtractor.h"

#include <cstdint>

namespace llvm {
namespace xray {

namespace {

// Keep this in sync with the values written in the XRay FDR mode runtime in
// compiler-rt.
enum MetadataRecordKinds : uint8_t {
  NewBufferKind,
  EndOfBufferKind,
  NewCPUIdKind,
  TSCWrapKind,
  WalltimeMarkerKind,
  CustomEventMarkerKind,
  CallArgumentKind,
  BufferExtentsKind,
  TypedEventMarkerKind,
  PidKind,
  // This is an end marker, used to identify the upper bound for this enum.
  EnumEndMarker,
};

Expected<std::unique_ptr<Record>>
metadataRecordType(const XRayFileHeader &Header, uint8_t T) {

  if (T >= static_cast<uint8_t>(MetadataRecordKinds::EnumEndMarker))
    return createStringError(std::make_error_code(std::errc::invalid_argument),
                             "Invalid metadata record type: %d", T);
  switch (T) {
  case MetadataRecordKinds::NewBufferKind:
    return std::make_unique<NewBufferRecord>();
  case MetadataRecordKinds::EndOfBufferKind:
    if (Header.Version >= 2)
      return createStringError(
          std::make_error_code(std::errc::executable_format_error),
          "End of buffer records are no longer supported starting version "
          "2 of the log.");
    return std::make_unique<EndBufferRecord>();
  case MetadataRecordKinds::NewCPUIdKind:
    return std::make_unique<NewCPUIDRecord>();
  case MetadataRecordKinds::TSCWrapKind:
    return std::make_unique<TSCWrapRecord>();
  case MetadataRecordKinds::WalltimeMarkerKind:
    return std::make_unique<WallclockRecord>();
  case MetadataRecordKinds::CustomEventMarkerKind:
    if (Header.Version >= 5)
      return std::make_unique<CustomEventRecordV5>();
    return std::make_unique<CustomEventRecord>();
  case MetadataRecordKinds::CallArgumentKind:
    return std::make_unique<CallArgRecord>();
  case MetadataRecordKinds::BufferExtentsKind:
    return std::make_unique<BufferExtents>();
  case MetadataRecordKinds::TypedEventMarkerKind:
    return std::make_unique<TypedEventRecord>();
  case MetadataRecordKinds::PidKind:
    return std::make_unique<PIDRecord>();
  case MetadataRecordKinds::EnumEndMarker:
    llvm_unreachable("Invalid MetadataRecordKind");
  }
  llvm_unreachable("Unhandled MetadataRecordKinds enum value");
}

constexpr bool isMetadataIntroducer(uint8_t FirstByte) {
  return FirstByte & 0x01u;
}

} // namespace

Expected<std::unique_ptr<Record>>
FileBasedRecordProducer::findNextBufferExtent() {
  // We seek one byte at a time until we find a suitable buffer extents metadata
  // record introducer.
  std::unique_ptr<Record> R;
  while (!R) {
    auto PreReadOffset = OffsetPtr;
    uint8_t FirstByte = E.getU8(&OffsetPtr);
    if (OffsetPtr == PreReadOffset)
      return createStringError(
          std::make_error_code(std::errc::executable_format_error),
          "Failed reading one byte from offset %" PRId64 ".", OffsetPtr);

    if (isMetadataIntroducer(FirstByte)) {
      auto LoadedType = FirstByte >> 1;
      if (LoadedType == MetadataRecordKinds::BufferExtentsKind) {
        auto MetadataRecordOrErr = metadataRecordType(Header, LoadedType);
        if (!MetadataRecordOrErr)
          return MetadataRecordOrErr.takeError();

        R = std::move(MetadataRecordOrErr.get());
        RecordInitializer RI(E, OffsetPtr);
        if (auto Err = R->apply(RI))
          return std::move(Err);
        return std::move(R);
      }
    }
  }
  llvm_unreachable("Must always terminate with either an error or a record.");
}

Expected<std::unique_ptr<Record>> FileBasedRecordProducer::produce() {
  // First, we set up our result record.
  std::unique_ptr<Record> R;

  // Before we do any further reading, we should check whether we're at the end
  // of the current buffer we're been consuming. In FDR logs version >= 3, we
  // rely on the buffer extents record to determine how many bytes we should be
  // considering as valid records.
  if (Header.Version >= 3 && CurrentBufferBytes == 0) {
    // Find the next buffer extents record.
    auto BufferExtentsOrError = findNextBufferExtent();
    if (!BufferExtentsOrError)
      return joinErrors(
          BufferExtentsOrError.takeError(),
          createStringError(
              std::make_error_code(std::errc::executable_format_error),
              "Failed to find the next BufferExtents record."));

    R = std::move(BufferExtentsOrError.get());
    assert(R != nullptr);
    assert(isa<BufferExtents>(R.get()));
    auto BE = cast<BufferExtents>(R.get());
    CurrentBufferBytes = BE->size();
    return std::move(R);
  }

  //
  // At the top level, we read one byte to determine the type of the record to
  // create. This byte will comprise of the following bits:
  //
  //   - offset 0: A '1' indicates a metadata record, a '0' indicates a function
  //     record.
  //   - offsets 1-7: For metadata records, this will indicate the kind of
  //     metadata record should be loaded.
  //
  // We read first byte, then create the appropriate type of record to consume
  // the rest of the bytes.
  auto PreReadOffset = OffsetPtr;
  uint8_t FirstByte = E.getU8(&OffsetPtr);
  if (OffsetPtr == PreReadOffset)
    return createStringError(
        std::make_error_code(std::errc::executable_format_error),
        "Failed reading one byte from offset %" PRId64 ".", OffsetPtr);

  // For metadata records, handle especially here.
  if (isMetadataIntroducer(FirstByte)) {
    auto LoadedType = FirstByte >> 1;
    auto MetadataRecordOrErr = metadataRecordType(Header, LoadedType);
    if (!MetadataRecordOrErr)
      return joinErrors(
          MetadataRecordOrErr.takeError(),
          createStringError(
              std::make_error_code(std::errc::executable_format_error),
              "Encountered an unsupported metadata record (%d) "
              "at offset %" PRId64 ".",
              LoadedType, PreReadOffset));
    R = std::move(MetadataRecordOrErr.get());
  } else {
    R = std::make_unique<FunctionRecord>();
  }
  RecordInitializer RI(E, OffsetPtr);

  if (auto Err = R->apply(RI))
    return std::move(Err);

  // If we encountered a BufferExtents record, we should record the remaining
  // bytes for the current buffer, to determine when we should start ignoring
  // potentially malformed data and looking for buffer extents records.
  if (auto BE = dyn_cast<BufferExtents>(R.get())) {
    CurrentBufferBytes = BE->size();
  } else if (Header.Version >= 3) {
    if (OffsetPtr - PreReadOffset > CurrentBufferBytes)
      return createStringError(
          std::make_error_code(std::errc::executable_format_error),
          "Buffer over-read at offset %" PRId64 " (over-read by %" PRId64
          " bytes); Record Type = %s.",
          OffsetPtr, (OffsetPtr - PreReadOffset) - CurrentBufferBytes,
          Record::kindToString(R->getRecordType()).data());

    CurrentBufferBytes -= OffsetPtr - PreReadOffset;
  }
  assert(R != nullptr);
  return std::move(R);
}

} // namespace xray
} // namespace llvm
