//===- llvm/unittest/XRay/FDRProducerConsumerTest.cpp -----------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// 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 std::make_unique<NewBufferRecord>(1);
}

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

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

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

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

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

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

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

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

template <> std::unique_ptr<Record> MakeRecord<TypedEventRecord>() {
  return std::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 = std::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 = std::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);
  uint64_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);
  uint64_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
