//===-- ProcessorTrace.cpp ------------------------------------ -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <algorithm>
#include <fstream>

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"

#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "ProcessorTrace.h"
#include "lldb/Host/linux/Support.h"

#include <sys/syscall.h>

using namespace lldb;
using namespace lldb_private;
using namespace process_linux;
using namespace llvm;

lldb::user_id_t ProcessorTraceMonitor::m_trace_num = 1;

Status ProcessorTraceMonitor::GetTraceConfig(TraceOptions &config) const {
#ifndef PERF_ATTR_SIZE_VER5
  llvm_unreachable("perf event not supported");
#else
  Status error;

  config.setType(lldb::TraceType::eTraceTypeProcessorTrace);
  config.setMetaDataBufferSize(m_mmap_meta->data_size);

  config.setTraceBufferSize(m_mmap_meta->aux_size);

  error = GetCPUType(config);

  return error;
#endif
}

Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
                                         const TraceOptions &config) {
#ifndef PERF_ATTR_SIZE_VER5
  llvm_unreachable("perf event not supported");
#else
  Status error;
  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));

  LLDB_LOG(log, "called thread id {0}", tid);
  uint64_t page_size = getpagesize();
  uint64_t bufsize = config.getTraceBufferSize();
  uint64_t metabufsize = config.getMetaDataBufferSize();

  uint64_t numpages = static_cast<uint64_t>(
      llvm::PowerOf2Floor((bufsize + page_size - 1) / page_size));
  numpages = std::max<uint64_t>(1, numpages);
  bufsize = page_size * numpages;

  numpages = static_cast<uint64_t>(
      llvm::PowerOf2Floor((metabufsize + page_size - 1) / page_size));
  metabufsize = page_size * numpages;

  perf_event_attr attr;
  memset(&attr, 0, sizeof(attr));
  attr.size = sizeof(attr);
  attr.exclude_kernel = 1;
  attr.sample_type = PERF_SAMPLE_TIME;
  attr.sample_id_all = 1;
  attr.exclude_hv = 1;
  attr.exclude_idle = 1;
  attr.mmap = 1;

  int intel_pt_type = 0;

  auto ret = llvm::MemoryBuffer::getFileAsStream(
      "/sys/bus/event_source/devices/intel_pt/type");
  if (!ret) {
    LLDB_LOG(log, "failed to open Config file");
    return ret.getError();
  }

  StringRef rest = ret.get()->getBuffer();
  if (rest.empty() || rest.trim().getAsInteger(10, intel_pt_type)) {
    LLDB_LOG(log, "failed to read Config file");
    error.SetErrorString("invalid file");
    return error;
  }

  rest.trim().getAsInteger(10, intel_pt_type);
  LLDB_LOG(log, "intel pt type {0}", intel_pt_type);
  attr.type = intel_pt_type;

  LLDB_LOG(log, "meta buffer size {0}", metabufsize);
  LLDB_LOG(log, "buffer size {0} ", bufsize);

  if (error.Fail()) {
    LLDB_LOG(log, "Status in custom config");

    return error;
  }

  errno = 0;
  auto fd =
      syscall(SYS_perf_event_open, &attr, static_cast<::tid_t>(tid), -1, -1, 0);
  if (fd == -1) {
    LLDB_LOG(log, "syscall error {0}", errno);
    error.SetErrorString("perf event syscall Failed");
    return error;
  }

  m_fd = std::unique_ptr<int, file_close>(new int(fd), file_close());

  errno = 0;
  auto base =
      mmap(NULL, (metabufsize + page_size), PROT_WRITE, MAP_SHARED, fd, 0);

  if (base == MAP_FAILED) {
    LLDB_LOG(log, "mmap base error {0}", errno);
    error.SetErrorString("Meta buffer allocation failed");
    return error;
  }

  m_mmap_meta = std::unique_ptr<perf_event_mmap_page, munmap_delete>(
      reinterpret_cast<perf_event_mmap_page *>(base),
      munmap_delete(metabufsize + page_size));

  m_mmap_meta->aux_offset = m_mmap_meta->data_offset + m_mmap_meta->data_size;
  m_mmap_meta->aux_size = bufsize;

  errno = 0;
  auto mmap_aux = mmap(NULL, bufsize, PROT_READ, MAP_SHARED, fd,
                       static_cast<long int>(m_mmap_meta->aux_offset));

  if (mmap_aux == MAP_FAILED) {
    LLDB_LOG(log, "second mmap done {0}", errno);
    error.SetErrorString("Trace buffer allocation failed");
    return error;
  }
  m_mmap_aux = std::unique_ptr<uint8_t, munmap_delete>(
      reinterpret_cast<uint8_t *>(mmap_aux), munmap_delete(bufsize));
  return error;
#endif
}

llvm::MutableArrayRef<uint8_t> ProcessorTraceMonitor::GetDataBuffer() {
#ifndef PERF_ATTR_SIZE_VER5
  llvm_unreachable("perf event not supported");
#else
  return MutableArrayRef<uint8_t>(
      (reinterpret_cast<uint8_t *>(m_mmap_meta.get()) +
       m_mmap_meta->data_offset),
      m_mmap_meta->data_size);
#endif
}

llvm::MutableArrayRef<uint8_t> ProcessorTraceMonitor::GetAuxBuffer() {
#ifndef PERF_ATTR_SIZE_VER5
  llvm_unreachable("perf event not supported");
#else
  return MutableArrayRef<uint8_t>(m_mmap_aux.get(), m_mmap_meta->aux_size);
#endif
}

Status ProcessorTraceMonitor::GetCPUType(TraceOptions &config) {

  Status error;
  uint64_t cpu_family = -1;
  uint64_t model = -1;
  uint64_t stepping = -1;
  std::string vendor_id;

  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));

  auto BufferOrError = getProcFile("cpuinfo");
  if (!BufferOrError)
    return BufferOrError.getError();

  LLDB_LOG(log, "GetCPUType Function");

  StringRef Rest = BufferOrError.get()->getBuffer();
  while (!Rest.empty()) {
    StringRef Line;
    std::tie(Line, Rest) = Rest.split('\n');

    SmallVector<StringRef, 2> columns;
    Line.split(columns, StringRef(":"), -1, false);

    if (columns.size() < 2)
      continue; // continue searching

    columns[1] = columns[1].trim(" ");
    if (columns[0].contains("cpu family") &&
        columns[1].getAsInteger(10, cpu_family))
      continue;

    else if (columns[0].contains("model") && columns[1].getAsInteger(10, model))
      continue;

    else if (columns[0].contains("stepping") &&
             columns[1].getAsInteger(10, stepping))
      continue;

    else if (columns[0].contains("vendor_id")) {
      vendor_id = columns[1].str();
      if (!vendor_id.empty())
        continue;
    }
    LLDB_LOG(log, "{0}:{1}:{2}:{3}", cpu_family, model, stepping, vendor_id);

    if ((cpu_family != static_cast<uint64_t>(-1)) &&
        (model != static_cast<uint64_t>(-1)) &&
        (stepping != static_cast<uint64_t>(-1)) && (!vendor_id.empty())) {
      auto params_dict = std::make_shared<StructuredData::Dictionary>();
      params_dict->AddIntegerItem("cpu_family", cpu_family);
      params_dict->AddIntegerItem("cpu_model", model);
      params_dict->AddIntegerItem("cpu_stepping", stepping);
      params_dict->AddStringItem("cpu_vendor", vendor_id);

      llvm::StringRef intel_custom_params_key("intel-pt");

      auto intel_custom_params = std::make_shared<StructuredData::Dictionary>();
      intel_custom_params->AddItem(
          intel_custom_params_key,
          StructuredData::ObjectSP(std::move(params_dict)));

      config.setTraceParams(intel_custom_params);
      return error; // we are done
    }
  }

  error.SetErrorString("cpu info not found");
  return error;
}

llvm::Expected<ProcessorTraceMonitorUP>
ProcessorTraceMonitor::Create(lldb::pid_t pid, lldb::tid_t tid,
                              const TraceOptions &config,
                              bool useProcessSettings) {

  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));

  Status error;
  if (tid == LLDB_INVALID_THREAD_ID) {
    error.SetErrorString("thread not specified");
    return error.ToError();
  }

  ProcessorTraceMonitorUP pt_monitor_up(new ProcessorTraceMonitor);

  error = pt_monitor_up->StartTrace(pid, tid, config);
  if (error.Fail())
    return error.ToError();

  pt_monitor_up->SetThreadID(tid);

  if (useProcessSettings) {
    pt_monitor_up->SetTraceID(0);
  } else {
    pt_monitor_up->SetTraceID(m_trace_num++);
    LLDB_LOG(log, "Trace ID {0}", m_trace_num);
  }
  return std::move(pt_monitor_up);
}

Status
ProcessorTraceMonitor::ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
                                        size_t offset) {
#ifndef PERF_ATTR_SIZE_VER5
  llvm_unreachable("perf event not supported");
#else
  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
  Status error;
  uint64_t head = m_mmap_meta->aux_head;

  LLDB_LOG(log, "Aux size -{0} , Head - {1}", m_mmap_meta->aux_size, head);

  /**
   * When configured as ring buffer, the aux buffer keeps wrapping around
   * the buffer and its not possible to detect how many times the buffer
   * wrapped. Initially the buffer is filled with zeros,as shown below
   * so in order to get complete buffer we first copy firstpartsize, followed
   * by any left over part from beginning to aux_head
   *
   * aux_offset [d,d,d,d,d,d,d,d,0,0,0,0,0,0,0,0,0,0,0] aux_size
   *                 aux_head->||<- firstpartsize  ->|
   *
   * */

  ReadCyclicBuffer(buffer, GetAuxBuffer(), static_cast<size_t>(head), offset);
  LLDB_LOG(log, "ReadCyclic BUffer Done");
  return error;
#endif
}

Status
ProcessorTraceMonitor::ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
                                         size_t offset) {
#ifndef PERF_ATTR_SIZE_VER5
  llvm_unreachable("perf event not supported");
#else
  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
  uint64_t bytes_remaining = buffer.size();
  Status error;

  uint64_t head = m_mmap_meta->data_head;

  /*
   * The data buffer and aux buffer have different implementations
   * with respect to their definition of head pointer. In the case
   * of Aux data buffer the head always wraps around the aux buffer
   * and we don't need to care about it, whereas the data_head keeps
   * increasing and needs to be wrapped by modulus operator
   */

  LLDB_LOG(log, "bytes_remaining - {0}", bytes_remaining);

  auto data_buffer = GetDataBuffer();

  if (head > data_buffer.size()) {
    head = head % data_buffer.size();
    LLDB_LOG(log, "Data size -{0} Head - {1}", m_mmap_meta->data_size, head);

    ReadCyclicBuffer(buffer, data_buffer, static_cast<size_t>(head), offset);
    bytes_remaining -= buffer.size();
  } else {
    LLDB_LOG(log, "Head - {0}", head);
    if (offset >= head) {
      LLDB_LOG(log, "Invalid Offset ");
      error.SetErrorString("invalid offset");
      buffer = buffer.slice(buffer.size());
      return error;
    }

    auto data = data_buffer.slice(offset, (head - offset));
    auto remaining = std::copy(data.begin(), data.end(), buffer.begin());
    bytes_remaining -= (remaining - buffer.begin());
  }
  buffer = buffer.drop_back(bytes_remaining);
  return error;
#endif
}

void ProcessorTraceMonitor::ReadCyclicBuffer(
    llvm::MutableArrayRef<uint8_t> &dst, llvm::MutableArrayRef<uint8_t> src,
    size_t src_cyc_index, size_t offset) {

  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));

  if (dst.empty() || src.empty()) {
    dst = dst.drop_back(dst.size());
    return;
  }

  if (dst.data() == nullptr || src.data() == nullptr) {
    dst = dst.drop_back(dst.size());
    return;
  }

  if (src_cyc_index > src.size()) {
    dst = dst.drop_back(dst.size());
    return;
  }

  if (offset >= src.size()) {
    LLDB_LOG(log, "Too Big offset ");
    dst = dst.drop_back(dst.size());
    return;
  }

  llvm::SmallVector<MutableArrayRef<uint8_t>, 2> parts = {
      src.slice(src_cyc_index), src.take_front(src_cyc_index)};

  if (offset > parts[0].size()) {
    parts[1] = parts[1].slice(offset - parts[0].size());
    parts[0] = parts[0].drop_back(parts[0].size());
  } else if (offset == parts[0].size()) {
    parts[0] = parts[0].drop_back(parts[0].size());
  } else {
    parts[0] = parts[0].slice(offset);
  }
  auto next = dst.begin();
  auto bytes_left = dst.size();
  for (auto part : parts) {
    size_t chunk_size = std::min(part.size(), bytes_left);
    next = std::copy_n(part.begin(), chunk_size, next);
    bytes_left -= chunk_size;
  }
  dst = dst.drop_back(bytes_left);
}
