// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/performance/insntrace/ktrace_controller.h"

#include <errno.h>
#include <fcntl.h>
#include <lib/fdio/directory.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/zircon-internal/ktrace.h>
#include <lib/zx/channel.h>
#include <unistd.h>
#include <zircon/status.h>

#include <fbl/unique_fd.h>

#include "src/lib/debugger_utils/util.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "src/performance/insntrace/utils.h"

namespace insntrace {

constexpr char kKtraceControllerSvc[] = "/svc/fuchsia.tracing.kernel.Controller";
constexpr char kKtraceReaderSvc[] = "/svc/fuchsia.tracing.kernel.Reader";

zx_status_t OpenKtraceControllerChannel(
    fuchsia::tracing::kernel::ControllerSyncPtr* out_controller_ptr) {
  zx_status_t status = fdio_service_connect(
      kKtraceControllerSvc, out_controller_ptr->NewRequest().TakeChannel().release());
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Error connecting to " << kKtraceControllerSvc << ": " << status;
    return status;
  }
  return status;
}

zx_status_t OpenKtraceReaderChannel(fuchsia::tracing::kernel::ReaderSyncPtr* out_reader_ptr) {
  zx_status_t status =
      fdio_service_connect(kKtraceReaderSvc, out_reader_ptr->NewRequest().TakeChannel().release());
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Error connecting to " << kKtraceReaderSvc << ": " << status;
    return status;
  }
  return status;
}

bool RequestKtraceStart(const fuchsia::tracing::kernel::ControllerSyncPtr& ktrace,
                        uint32_t group_mask) {
  using BufferingMode = ::fuchsia::tracing::provider::BufferingMode;
  zx_status_t start_status;
  zx_status_t status = ktrace->Start(group_mask, BufferingMode::ONESHOT, &start_status);
  LogFidlFailure("Ktrace start", status, start_status);
  return status == ZX_OK && start_status == ZX_OK;
}

void RequestKtraceStop(const fuchsia::tracing::kernel::ControllerSyncPtr& ktrace) {
  zx_status_t stop_status;
  zx_status_t status = ktrace->Stop(&stop_status);
  LogFidlFailure("Ktrace stop", status, stop_status);
}

void RequestKtraceRewind(const fuchsia::tracing::kernel::ControllerSyncPtr& ktrace) {
  zx_status_t rewind_status;
  zx_status_t status = ktrace->Rewind(&rewind_status);
  LogFidlFailure("Ktrace rewind", status, rewind_status);
}

void DumpKtraceBuffer(const char* output_path_prefix, const char* output_path_suffix) {
  fuchsia::tracing::kernel::ReaderSyncPtr ktrace;
  if (OpenKtraceReaderChannel(&ktrace) != ZX_OK) {
    return;
  }

  std::string ktrace_output_path =
      fxl::StringPrintf("%s.%s", output_path_prefix, output_path_suffix);
  const char* ktrace_c_path = ktrace_output_path.c_str();

  fbl::unique_fd dest_fd(open(ktrace_c_path, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR));
  if (dest_fd.is_valid()) {
    std::vector<uint8_t> buf;
    size_t read_size = 1024;
    size_t offset = 0;
    zx_status_t out_status;
    zx_status_t status;
    while ((status = ktrace->ReadAt(read_size, offset, &out_status, &buf)) == ZX_OK &&
           out_status == ZX_OK) {
      if (buf.size() == 0) {
        break;
      }
      size_t bytes_written = write(dest_fd.get(), buf.data(), buf.size());
      if (bytes_written != buf.size()) {
        FX_LOGS(ERROR) << "error writing " << ktrace_c_path;
        break;
      }
      offset += buf.size();
    }
  } else {
    FX_LOGS(ERROR) << fxl::StringPrintf("unable to create %s", ktrace_c_path)
                   << ", errno=" << debugger_utils::ErrnoString(errno);
  }
}

}  // namespace insntrace
