//===-- ProcessorTrace.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
//
//===----------------------------------------------------------------------===//

#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(nullptr, (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(nullptr, 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);
}
