//===- llvm/unittest/XRay/FDRProducerConsumerTest.cpp -----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Test for round-trip record writing and reading.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/XRay/FDRLogBuilder.h"
#include "llvm/XRay/FDRRecordConsumer.h"
#include "llvm/XRay/FDRRecordProducer.h"
#include "llvm/XRay/FDRRecords.h"
#include "llvm/XRay/FDRTraceWriter.h"
#include "llvm/XRay/FileHeaderReader.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <string>
#include <tuple>

namespace llvm {
namespace xray {
namespace {

using ::testing::Eq;
using ::testing::IsEmpty;
using ::testing::Not;
using ::testing::SizeIs;

template <class RecordType> std::unique_ptr<Record> MakeRecord();

template <> std::unique_ptr<Record> MakeRecord<NewBufferRecord>() {
  return make_unique<NewBufferRecord>(1);
}

template <> std::unique_ptr<Record> MakeRecord<NewCPUIDRecord>() {
  return make_unique<NewCPUIDRecord>(1, 2);
}

template <> std::unique_ptr<Record> MakeRecord<TSCWrapRecord>() {
  return make_unique<TSCWrapRecord>(1);
}

template <> std::unique_ptr<Record> MakeRecord<WallclockRecord>() {
  return make_unique<WallclockRecord>(1, 2);
}

template <> std::unique_ptr<Record> MakeRecord<CustomEventRecord>() {
  return make_unique<CustomEventRecord>(4, 1, 2, "data");
}

template <> std::unique_ptr<Record> MakeRecord<CallArgRecord>() {
  return make_unique<CallArgRecord>(1);
}

template <> std::unique_ptr<Record> MakeRecord<PIDRecord>() {
  return make_unique<PIDRecord>(1);
}

template <> std::unique_ptr<Record> MakeRecord<FunctionRecord>() {
  return make_unique<FunctionRecord>(RecordTypes::ENTER, 1, 2);
}

template <> std::unique_ptr<Record> MakeRecord<CustomEventRecordV5>() {
  return make_unique<CustomEventRecordV5>(4, 1, "data");
}

template <> std::unique_ptr<Record> MakeRecord<TypedEventRecord>() {
  return make_unique<TypedEventRecord>(4, 1, 2, "data");
}

template <class T> class RoundTripTest : public ::testing::Test {
public:
  RoundTripTest() : Data(), OS(Data) {
    H.Version = 4;
    H.Type = 1;
    H.ConstantTSC = true;
    H.NonstopTSC = true;
    H.CycleFrequency = 3e9;

    Writer = make_unique<FDRTraceWriter>(OS, H);
    Rec = MakeRecord<T>();
  }

protected:
  std::string Data;
  raw_string_ostream OS;
  XRayFileHeader H;
  std::unique_ptr<FDRTraceWriter> Writer;
  std::unique_ptr<Record> Rec;
};

TYPED_TEST_CASE_P(RoundTripTest);

template <class T> class RoundTripTestV5 : public ::testing::Test {
public:
  RoundTripTestV5() : Data(), OS(Data) {
    H.Version = 5;
    H.Type = 1;
    H.ConstantTSC = true;
    H.NonstopTSC = true;
    H.CycleFrequency = 3e9;

    Writer = make_unique<FDRTraceWriter>(OS, H);
    Rec = MakeRecord<T>();
  }

protected:
  std::string Data;
  raw_string_ostream OS;
  XRayFileHeader H;
  std::unique_ptr<FDRTraceWriter> Writer;
  std::unique_ptr<Record> Rec;
};

TYPED_TEST_CASE_P(RoundTripTestV5);

// This test ensures that the writing and reading implementations are in sync --
// that given write(read(write(R))) == R.
TYPED_TEST_P(RoundTripTest, RoundTripsSingleValue) {
  // Always write a buffer extents record which will cover the correct size of
  // the record, for version 3 and up.
  BufferExtents BE(200);
  ASSERT_FALSE(errorToBool(BE.apply(*this->Writer)));
  auto &R = this->Rec;
  ASSERT_FALSE(errorToBool(R->apply(*this->Writer)));
  this->OS.flush();

  DataExtractor DE(this->Data, sys::IsLittleEndianHost, 8);
  uint32_t OffsetPtr = 0;
  auto HeaderOrErr = readBinaryFormatHeader(DE, OffsetPtr);
  if (!HeaderOrErr)
    FAIL() << HeaderOrErr.takeError();

  FileBasedRecordProducer P(HeaderOrErr.get(), DE, OffsetPtr);
  std::vector<std::unique_ptr<Record>> Records;
  LogBuilderConsumer C(Records);
  while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
    auto R = P.produce();
    if (!R)
      FAIL() << R.takeError();
    if (auto E = C.consume(std::move(R.get())))
      FAIL() << E;
  }
  ASSERT_THAT(Records, Not(IsEmpty()));
  std::string Data2;
  raw_string_ostream OS2(Data2);
  FDRTraceWriter Writer2(OS2, this->H);
  for (auto &P : Records)
    ASSERT_FALSE(errorToBool(P->apply(Writer2)));
  OS2.flush();

  EXPECT_EQ(Data2.substr(sizeof(XRayFileHeader)),
            this->Data.substr(sizeof(XRayFileHeader)));
  ASSERT_THAT(Records, SizeIs(2));
  EXPECT_THAT(Records[1]->getRecordType(), Eq(R->getRecordType()));
}

REGISTER_TYPED_TEST_CASE_P(RoundTripTest, RoundTripsSingleValue);

// We duplicate the above case for the V5 version using different types and
// encodings.
TYPED_TEST_P(RoundTripTestV5, RoundTripsSingleValue) {
  BufferExtents BE(200);
  ASSERT_FALSE(errorToBool(BE.apply(*this->Writer)));
  auto &R = this->Rec;
  ASSERT_FALSE(errorToBool(R->apply(*this->Writer)));
  this->OS.flush();

  DataExtractor DE(this->Data, sys::IsLittleEndianHost, 8);
  uint32_t OffsetPtr = 0;
  auto HeaderOrErr = readBinaryFormatHeader(DE, OffsetPtr);
  if (!HeaderOrErr)
    FAIL() << HeaderOrErr.takeError();

  FileBasedRecordProducer P(HeaderOrErr.get(), DE, OffsetPtr);
  std::vector<std::unique_ptr<Record>> Records;
  LogBuilderConsumer C(Records);
  while (DE.isValidOffsetForDataOfSize(OffsetPtr, 1)) {
    auto R = P.produce();
    if (!R)
      FAIL() << R.takeError();
    if (auto E = C.consume(std::move(R.get())))
      FAIL() << E;
  }
  ASSERT_THAT(Records, Not(IsEmpty()));
  std::string Data2;
  raw_string_ostream OS2(Data2);
  FDRTraceWriter Writer2(OS2, this->H);
  for (auto &P : Records)
    ASSERT_FALSE(errorToBool(P->apply(Writer2)));
  OS2.flush();

  EXPECT_EQ(Data2.substr(sizeof(XRayFileHeader)),
            this->Data.substr(sizeof(XRayFileHeader)));
  ASSERT_THAT(Records, SizeIs(2));
  EXPECT_THAT(Records[1]->getRecordType(), Eq(R->getRecordType()));
}

REGISTER_TYPED_TEST_CASE_P(RoundTripTestV5, RoundTripsSingleValue);

// These are the record types we support for v4 and below.
using RecordTypes =
    ::testing::Types<NewBufferRecord, NewCPUIDRecord, TSCWrapRecord,
                     WallclockRecord, CustomEventRecord, CallArgRecord,
                     PIDRecord, FunctionRecord>;
INSTANTIATE_TYPED_TEST_CASE_P(Records, RoundTripTest, RecordTypes);

// For V5, we have two new types we're supporting.
using RecordTypesV5 =
    ::testing::Types<NewBufferRecord, NewCPUIDRecord, TSCWrapRecord,
                     WallclockRecord, CustomEventRecordV5, TypedEventRecord,
                     CallArgRecord, PIDRecord, FunctionRecord>;
INSTANTIATE_TYPED_TEST_CASE_P(Records, RoundTripTestV5, RecordTypesV5);

} // namespace
} // namespace xray
} // namespace llvm
