//===-- test_helpers.cpp --------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file is a part of XRay, a function call tracing system.
//
//===----------------------------------------------------------------------===//
#include "test_helpers.h"
#include "xray/xray_records.h"
#include "xray_buffer_queue.h"
#include "xray_fdr_log_writer.h"
#include <type_traits>

// TODO: Move these to llvm/include/Testing/XRay/...
namespace llvm {
namespace xray {

std::string RecordTypeAsString(RecordTypes T) {
  switch (T) {
  case RecordTypes::ENTER:
    return "llvm::xray::RecordTypes::ENTER";
  case RecordTypes::EXIT:
    return "llvm::xray::RecordTypes::EXIT";
  case RecordTypes::TAIL_EXIT:
    return "llvm::xray::RecordTypes::TAIL_EXIT";
  case RecordTypes::ENTER_ARG:
    return "llvm::xray::RecordTypes::ENTER_ARG";
  case RecordTypes::CUSTOM_EVENT:
    return "llvm::xray::RecordTypes::CUSTOM_EVENT";
  case RecordTypes::TYPED_EVENT:
    return "llvm::xray::RecordTypes::TYPED_EVENT";
  }
  return "<UNKNOWN>";
}

void PrintTo(RecordTypes T, std::ostream *OS) {
  *OS << RecordTypeAsString(T);
}

void PrintTo(const XRayRecord &R, std::ostream *OS) {
  *OS << "XRayRecord { CPU = " << R.CPU
      << "; Type = " << RecordTypeAsString(R.Type) << "; FuncId = " << R.FuncId
      << "; TSC = " << R.TSC << "; TId = " << R.TId << "; PId = " << R.PId
      << " Args = " << ::testing::PrintToString(R.CallArgs) << " }";
}

void PrintTo(const Trace &T, std::ostream *OS) {
  const auto &H = T.getFileHeader();
  *OS << "XRay Trace:\nHeader: { Version = " << H.Version
      << "; Type = " << H.Type
      << "; ConstantTSC = " << ::testing::PrintToString(H.ConstantTSC)
      << "; NonstopTSC = " << ::testing::PrintToString(H.NonstopTSC)
      << "; CycleFrequency = " << H.CycleFrequency << "; FreeFormData = '"
      << ::testing::PrintToString(H.FreeFormData) << "' }\n";
  for (const auto &R : T) {
    PrintTo(R, OS);
    *OS << "\n";
  }
}

} // namespace xray
} // namespace llvm

namespace __xray {

std::string serialize(BufferQueue &Buffers, int32_t Version) {
  std::string Serialized;
  std::aligned_storage<sizeof(XRayFileHeader), alignof(XRayFileHeader)>::type
      HeaderStorage;
  auto *Header = reinterpret_cast<XRayFileHeader *>(&HeaderStorage);
  new (Header) XRayFileHeader();
  Header->Version = Version;
  Header->Type = FileTypes::FDR_LOG;
  Header->CycleFrequency = 3e9;
  Header->ConstantTSC = 1;
  Header->NonstopTSC = 1;
  Serialized.append(reinterpret_cast<const char *>(&HeaderStorage),
                    sizeof(XRayFileHeader));
  Buffers.apply([&](const BufferQueue::Buffer &B) {
    auto Size = atomic_load_relaxed(B.Extents);
    auto Extents =
        createMetadataRecord<MetadataRecord::RecordKinds::BufferExtents>(Size);
    Serialized.append(reinterpret_cast<const char *>(&Extents),
                      sizeof(Extents));
    Serialized.append(reinterpret_cast<const char *>(B.Data), Size);
  });
  return Serialized;
}

} // namespace __xray
