//===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Define types and operations on these types that represent the different kinds
// of records we encounter in XRay flight data recorder mode traces.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
#define LLVM_LIB_XRAY_FDRRECORDS_H_

#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
#include "llvm/XRay/XRayRecord.h"
#include <cstdint>

namespace llvm {
namespace xray {

class RecordVisitor;
class RecordInitializer;

class Record {
protected:
  enum class Type {
    Unknown,
    Function,
    Metadata,
  };

public:
  Record(const Record &) = delete;
  Record(Record &&) = delete;
  Record &operator=(const Record &) = delete;
  Record &operator=(Record &&) = delete;
  Record() = default;

  virtual Type type() const = 0;

  // Each Record should be able to apply an abstract visitor, and choose the
  // appropriate function in the visitor to invoke, given its own type.
  virtual Error apply(RecordVisitor &V) = 0;

  virtual ~Record() = default;
};

class MetadataRecord : public Record {
protected:
  static constexpr int kMetadataBodySize = 15;
  friend class RecordInitializer;

public:
  enum class MetadataType : unsigned {
    Unknown,
    BufferExtents,
    WallClockTime,
    NewCPUId,
    TSCWrap,
    CustomEvent,
    CallArg,
    PIDEntry,
    NewBuffer,
    EndOfBuffer,
  };

  Type type() const override { return Type::Metadata; }

  // All metadata records must know to provide the type of their open
  // metadata record.
  virtual MetadataType metadataType() const = 0;

  virtual ~MetadataRecord() = default;
};

// What follows are specific Metadata record types which encapsulate the
// information associated with specific metadata record types in an FDR mode
// log.
class BufferExtents : public MetadataRecord {
  uint64_t Size = 0;
  friend class RecordInitializer;

public:
  BufferExtents() = default;
  explicit BufferExtents(uint64_t S) : MetadataRecord(), Size(S) {}

  MetadataType metadataType() const override {
    return MetadataType::BufferExtents;
  }

  uint64_t size() const { return Size; }

  Error apply(RecordVisitor &V) override;
};

class WallclockRecord : public MetadataRecord {
  uint64_t Seconds = 0;
  uint32_t Nanos = 0;
  friend class RecordInitializer;

public:
  WallclockRecord() = default;
  explicit WallclockRecord(uint64_t S, uint32_t N)
      : MetadataRecord(), Seconds(S), Nanos(N) {}

  MetadataType metadataType() const override {
    return MetadataType::WallClockTime;
  }

  uint64_t seconds() const { return Seconds; }
  uint32_t nanos() const { return Nanos; }

  Error apply(RecordVisitor &V) override;
};

class NewCPUIDRecord : public MetadataRecord {
  uint16_t CPUId = 0;
  uint64_t TSC = 0;
  friend class RecordInitializer;

public:
  NewCPUIDRecord() = default;
  NewCPUIDRecord(uint16_t C, uint64_t T) : MetadataRecord(), CPUId(C), TSC(T) {}

  MetadataType metadataType() const override { return MetadataType::NewCPUId; }

  uint16_t cpuid() const { return CPUId; }

  uint64_t tsc() const { return TSC; }

  Error apply(RecordVisitor &V) override;
};

class TSCWrapRecord : public MetadataRecord {
  uint64_t BaseTSC = 0;
  friend class RecordInitializer;

public:
  TSCWrapRecord() = default;
  explicit TSCWrapRecord(uint64_t B) : MetadataRecord(), BaseTSC(B) {}

  MetadataType metadataType() const override { return MetadataType::TSCWrap; }

  uint64_t tsc() const { return BaseTSC; }

  Error apply(RecordVisitor &V) override;
};

class CustomEventRecord : public MetadataRecord {
  int32_t Size = 0;
  uint64_t TSC = 0;
  std::string Data{};
  friend class RecordInitializer;

public:
  CustomEventRecord() = default;
  explicit CustomEventRecord(uint64_t S, uint64_t T, std::string D)
      : MetadataRecord(), Size(S), TSC(T), Data(std::move(D)) {}

  MetadataType metadataType() const override {
    return MetadataType::CustomEvent;
  }

  int32_t size() const { return Size; }
  uint64_t tsc() const { return TSC; }
  StringRef data() const { return Data; }

  Error apply(RecordVisitor &V) override;
};

class CallArgRecord : public MetadataRecord {
  uint64_t Arg;
  friend class RecordInitializer;

public:
  CallArgRecord() = default;
  explicit CallArgRecord(uint64_t A) : MetadataRecord(), Arg(A) {}

  MetadataType metadataType() const override { return MetadataType::CallArg; }

  uint64_t arg() const { return Arg; }

  Error apply(RecordVisitor &V) override;
};

class PIDRecord : public MetadataRecord {
  int32_t PID = 0;
  friend class RecordInitializer;

public:
  PIDRecord() = default;
  explicit PIDRecord(int32_t P) : MetadataRecord(), PID(P) {}

  MetadataType metadataType() const override { return MetadataType::PIDEntry; }

  int32_t pid() const { return PID; }

  Error apply(RecordVisitor &V) override;
};

class NewBufferRecord : public MetadataRecord {
  int32_t TID = 0;
  friend class RecordInitializer;

public:
  NewBufferRecord() = default;
  explicit NewBufferRecord(int32_t T) : MetadataRecord(), TID(T) {}

  MetadataType metadataType() const override { return MetadataType::NewBuffer; }

  int32_t tid() const { return TID; }

  Error apply(RecordVisitor &V) override;
};

class EndBufferRecord : public MetadataRecord {
public:
  EndBufferRecord() = default;

  MetadataType metadataType() const override {
    return MetadataType::EndOfBuffer;
  }

  Error apply(RecordVisitor &V) override;
};

class FunctionRecord : public Record {
  RecordTypes Kind;
  int32_t FuncId;
  uint32_t Delta;
  friend class RecordInitializer;

  static constexpr unsigned kFunctionRecordSize = 8;

public:
  FunctionRecord() = default;
  explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
      : Record(), Kind(K), FuncId(F), Delta(D) {}

  Type type() const override { return Type::Function; }

  // A function record is a concrete record type which has a number of common
  // properties.
  RecordTypes recordType() const { return Kind; }
  int32_t functionId() const { return FuncId; }
  uint32_t delta() const { return Delta; }

  Error apply(RecordVisitor &V) override;
};

class RecordVisitor {
public:
  virtual ~RecordVisitor() = default;

  // Support all specific kinds of records:
  virtual Error visit(BufferExtents &) = 0;
  virtual Error visit(WallclockRecord &) = 0;
  virtual Error visit(NewCPUIDRecord &) = 0;
  virtual Error visit(TSCWrapRecord &) = 0;
  virtual Error visit(CustomEventRecord &) = 0;
  virtual Error visit(CallArgRecord &) = 0;
  virtual Error visit(PIDRecord &) = 0;
  virtual Error visit(NewBufferRecord &) = 0;
  virtual Error visit(EndBufferRecord &) = 0;
  virtual Error visit(FunctionRecord &) = 0;
};

class RecordInitializer : public RecordVisitor {
  DataExtractor &E;
  uint32_t &OffsetPtr;

public:
  explicit RecordInitializer(DataExtractor &DE, uint32_t &OP)
      : RecordVisitor(), E(DE), OffsetPtr(OP) {}

  Error visit(BufferExtents &) override;
  Error visit(WallclockRecord &) override;
  Error visit(NewCPUIDRecord &) override;
  Error visit(TSCWrapRecord &) override;
  Error visit(CustomEventRecord &) override;
  Error visit(CallArgRecord &) override;
  Error visit(PIDRecord &) override;
  Error visit(NewBufferRecord &) override;
  Error visit(EndBufferRecord &) override;
  Error visit(FunctionRecord &) override;
};

} // namespace xray
} // namespace llvm

#endif // LLVM_LIB_XRAY_FDRRECORDS_H_
