// Copyright 2016 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 "garnet/bin/ktrace_provider/app.h"

#include <fcntl.h>
#include <unistd.h>

#include <fuchsia/tracing/kernel/c/fidl.h>
#include <lib/async/default.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <src/lib/fxl/arraysize.h>
#include <src/lib/fxl/logging.h>
#include <trace-engine/instrumentation.h>
#include <trace-provider/provider.h>
#include <zircon/device/ktrace.h>
#include <zircon/status.h>
#include <zircon/syscalls/log.h>

#include "garnet/bin/ktrace_provider/device_reader.h"
#include "garnet/bin/ktrace_provider/importer.h"

namespace ktrace_provider {
namespace {

constexpr char kKTraceDev[] = "/dev/misc/ktrace";

struct KTraceCategory {
  const char* name;
  uint32_t group;
};

constexpr KTraceCategory kGroupCategories[] = {
    {"kernel", KTRACE_GRP_ALL},
    {"kernel:meta", KTRACE_GRP_META},
    {"kernel:lifecycle", KTRACE_GRP_LIFECYCLE},
    {"kernel:sched", KTRACE_GRP_SCHEDULER},
    {"kernel:tasks", KTRACE_GRP_TASKS},
    {"kernel:ipc", KTRACE_GRP_IPC},
    {"kernel:irq", KTRACE_GRP_IRQ},
    {"kernel:probe", KTRACE_GRP_PROBE},
    {"kernel:arch", KTRACE_GRP_ARCH},
};

// Meta category to retain current contents of ktrace buffer.
constexpr char kRetainCategory[] = "kernel:retain";

constexpr char kLogCategory[] = "log";

zx::channel OpenKTrace() {
  int fd = open(kKTraceDev, O_WRONLY);
  if (fd < 0) {
    FXL_LOG(ERROR) << "Failed to open " << kKTraceDev << ": errno=" << errno;
    return zx::channel();
  }
  zx::channel channel;
  zx_status_t status =
      fdio_get_service_handle(fd, channel.reset_and_get_address());
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "Failed to get " << kKTraceDev
                   << " channel: " << zx_status_get_string(status);
    return zx::channel();
  }
  return channel;
}

void LogFidlFailure(const char* rqst_name, zx_status_t fidl_status,
                    zx_status_t rqst_status) {
  if (fidl_status != ZX_OK) {
    FXL_LOG(ERROR) << "Ktrace FIDL " << rqst_name
                   << " failed: status=" << fidl_status;
  } else if (rqst_status != ZX_OK) {
    FXL_LOG(ERROR) << "Ktrace " << rqst_name
                   << " failed: status=" << rqst_status;
  }
}

void RequestKtraceStop(const zx::channel& channel) {
  zx_status_t stop_status;
  zx_status_t status =
      fuchsia_tracing_kernel_ControllerStop(channel.get(), &stop_status);
  LogFidlFailure("stop", status, stop_status);
}

void RequestKtraceRewind(const zx::channel& channel) {
  zx_status_t rewind_status;
  zx_status_t status =
      fuchsia_tracing_kernel_ControllerRewind(channel.get(), &rewind_status);
  LogFidlFailure("rewind", status, rewind_status);
}

void RequestKtraceStart(const zx::channel& channel, uint32_t group_mask) {
  zx_status_t start_status;
  zx_status_t status = fuchsia_tracing_kernel_ControllerStart(
      channel.get(), group_mask, &start_status);
  LogFidlFailure("start", status, start_status);
}

}  // namespace

App::App(const fxl::CommandLine& command_line)
    : component_context_(sys::ComponentContext::Create()) {
  trace_observer_.Start(async_get_default_dispatcher(),
                        [this] { UpdateState(); });
}

App::~App() {}

void App::UpdateState() {
  uint32_t group_mask = 0;
  bool capture_log = false;
  bool retain_current_data = false;
  if (trace_state() == TRACE_STARTED) {
    size_t num_enabled_categories = 0;
    for (size_t i = 0; i < arraysize(kGroupCategories); i++) {
      auto& category = kGroupCategories[i];
      if (trace_is_category_enabled(category.name)) {
        group_mask |= category.group;
        ++num_enabled_categories;
      }
    }

    // Avoid capturing log traces in the default case by detecting whether all
    // categories are enabled or not.
    capture_log = trace_is_category_enabled(kLogCategory) &&
                  num_enabled_categories != arraysize(kGroupCategories);

    // The default case is everything is enabled, but |kRetainCategory| must be
    // explicitly passed.
    retain_current_data = trace_is_category_enabled(kRetainCategory) &&
                          num_enabled_categories != arraysize(kGroupCategories);
  }

  if (current_group_mask_ != group_mask) {
    StopKTrace();
    StartKTrace(group_mask, retain_current_data);
  }

  if (capture_log) {
    log_importer_.Start();
  } else {
    log_importer_.Stop();
  }
}

void App::StartKTrace(uint32_t group_mask, bool retain_current_data) {
  FXL_DCHECK(!context_);
  if (!group_mask) {
    return;  // nothing to trace
  }

  FXL_LOG(INFO) << "Starting ktrace";

  zx::channel channel = OpenKTrace();
  if (!channel) {
    return;
  }

  context_ = trace_acquire_prolonged_context();
  if (!context_) {
    // Tracing was disabled in the meantime.
    return;
  }
  current_group_mask_ = group_mask;

  RequestKtraceStop(channel);
  if (!retain_current_data) {
    RequestKtraceRewind(channel);
  }
  RequestKtraceStart(channel, group_mask);

  FXL_VLOG(1) << "Ktrace started";
}

void App::StopKTrace() {
  if (!context_) {
    return;  // not currently tracing
  }
  FXL_DCHECK(current_group_mask_);

  FXL_LOG(INFO) << "Stopping ktrace";

  {
    zx::channel channel = OpenKTrace();
    if (channel) {
      RequestKtraceStop(channel);
    }
  }

  // Acquire a context for writing to the trace buffer.
  auto buffer_context = trace_acquire_context();

  DeviceReader reader;
  Importer importer(buffer_context);
  if (!importer.Import(reader)) {
    FXL_LOG(ERROR) << "Errors encountered while importing ktrace data";
  }

  trace_release_context(buffer_context);
  trace_release_prolonged_context(context_);
  context_ = nullptr;
  current_group_mask_ = 0u;

  FXL_VLOG(1) << "Ktrace stopped";
}

}  // namespace ktrace_provider
