// 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/importer.h"

#include <fbl/algorithm.h>
#include <fbl/string_printf.h>
#include <zircon/syscalls.h>

#include "garnet/bin/ktrace_provider/reader.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/time/time_point.h"

namespace ktrace_provider {
namespace {

constexpr uint64_t ToUInt64(uint32_t lo, uint32_t hi) {
  return (static_cast<uint64_t>(hi) << 32) | lo;
}

// The kernel reports different thread state values through ktrace.
// These values must line up with those in "kernel/include/kernel/thread.h".
constexpr trace_thread_state_t ToTraceThreadState(int value) {
  switch (value) {
    case 0:  // THREAD_INITIAL
    case 1:  // THREAD_READY
      return ZX_THREAD_STATE_NEW;
    case 2:  // THREAD_RUNNING
      return ZX_THREAD_STATE_RUNNING;
    case 3:  // THREAD_BLOCKED
    case 4:  // THREAD_BLOCKED_READ_LOCK
    case 5:  // THREAD_SLEEPING
      return ZX_THREAD_STATE_BLOCKED;
    case 6:  // THREAD_SUSPENDED
      return ZX_THREAD_STATE_SUSPENDED;
    case 7:  // THREAD_DEATH
      return ZX_THREAD_STATE_DEAD;
    default:  // ???
      FXL_LOG(WARNING) << "Imported unknown thread state from ktrace: "
                       << value;
      return INT32_MAX;
  }
}

}  // namespace

#define MAKE_STRING(literal) \
  trace_context_make_registered_string_literal(context_, literal)

Importer::Importer(trace_context_t* context)
    : context_(context),
      tags_(GetTags()),
      kernel_string_ref_(MAKE_STRING("kernel")),
      unknown_category_ref_(MAKE_STRING("kernel:unknown")),
      arch_category_ref_(MAKE_STRING("kernel:arch")),
      meta_category_ref_(MAKE_STRING("kernel:meta")),
      lifecycle_category_ref_(MAKE_STRING("kernel:lifecycle")),
      tasks_category_ref_(MAKE_STRING("kernel:tasks")),
      ipc_category_ref_(MAKE_STRING("kernel:ipc")),
      irq_category_ref_(MAKE_STRING("kernel:irq")),
      probe_category_ref_(MAKE_STRING("kernel:probe")),
      sched_category_ref_(MAKE_STRING("kernel:sched")),
      syscall_category_ref_(MAKE_STRING("kernel:syscall")),
      channel_category_ref_(MAKE_STRING("kernel:channel")),
      vcpu_category_ref_(MAKE_STRING("kernel:vcpu")),
      channel_read_name_ref_(MAKE_STRING("read")),
      channel_write_name_ref_(MAKE_STRING("write")),
      num_bytes_name_ref_(MAKE_STRING("num_bytes")),
      num_handles_name_ref_(MAKE_STRING("num_handles")),
      page_fault_name_ref_(MAKE_STRING("page_fault")),
      vaddr_name_ref_(MAKE_STRING("vaddr")),
      flags_name_ref_(MAKE_STRING("flags")),
      exit_address_name_ref_(MAKE_STRING("exit_address")),
      arg0_name_ref_(MAKE_STRING("arg0")),
      arg1_name_ref_(MAKE_STRING("arg1")),
      kUnknownThreadRef(trace_make_unknown_thread_ref()) {}

#undef MAKE_STRING

Importer::~Importer() = default;

bool Importer::Import(Reader& reader) {
  trace_context_write_process_info_record(context_, kNoProcess,
                                          &kernel_string_ref_);

  auto start = fxl::TimePoint::Now();

  while (true) {
    if (auto record = reader.ReadNextRecord()) {
      if (!ImportRecord(record, KTRACE_LEN(record->tag))) {
        FXL_VLOG(2) << "Skipped ktrace record, tag=0x" << std::hex
                    << record->tag;
      }
    } else {
      break;
    }
  }

  size_t nr_bytes_read = reader.number_bytes_read();
  size_t nr_records_read = reader.number_records_read();

  // This is an INFO and not VLOG() as we currently always want to see this.
  FXL_LOG(INFO) << "Import of " << nr_records_read << " ktrace records"
                << "(" << nr_bytes_read << " bytes) took: "
                << (fxl::TimePoint::Now() - start).ToMicroseconds() << "us";

  return true;
}

bool Importer::ImportRecord(const ktrace_header_t* record, size_t record_size) {
  auto it = tags_.find(KTRACE_EVENT(record->tag));
  if (it != tags_.end()) {
    const TagInfo& tag_info = it->second;
    switch (tag_info.type) {
      case TagType::kBasic:
        return ImportBasicRecord(record, tag_info);
      case TagType::kQuad:
        if (sizeof(ktrace_rec_32b_t) > record_size)
          return false;
        return ImportQuadRecord(
            reinterpret_cast<const ktrace_rec_32b_t*>(record), tag_info);
      case TagType::kName:
        if (sizeof(ktrace_rec_name_t) > record_size)
          return false;
        return ImportNameRecord(
            reinterpret_cast<const ktrace_rec_name_t*>(record), tag_info);
    }
  }

  // TODO(eieio): Using this combination of bits and groups to select the record
  // type is a bit hacky due to how the kernel trace record is defined. Fixing
  // this requires a re-design or replacement with the same strategy used in the
  // rest of the system.
  const bool is_probe_group = KTRACE_GROUP(record->tag) & KTRACE_GRP_PROBE;
  const bool is_flow = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_FLOW;
  const bool is_begin = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_BEGIN;
  const bool is_end = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_END;
  const bool is_duration = !is_flow && (is_begin | is_end);

  if (is_probe_group)
    return ImportProbeRecord(record, record_size);
  else if (is_duration)
    return ImportDurationRecord(record, record_size);
  else if (is_flow)
    return ImportFlowRecord(record, record_size);

  return ImportUnknownRecord(record, record_size);
}

bool Importer::ImportBasicRecord(const ktrace_header_t* record,
                                 const TagInfo& tag_info) {
  FXL_VLOG(2) << "BASIC: tag=0x" << std::hex << record->tag << " ("
              << tag_info.name << "), tid=" << std::dec << record->tid
              << ", timestamp=" << record->ts;

  switch (KTRACE_EVENT(record->tag)) {
    case KTRACE_EVENT(TAG_IRQ_ENTER):
      return HandleIRQEnter(record->ts, record->tid & 0xff, record->tid >> 8);
    case KTRACE_EVENT(TAG_IRQ_EXIT):
      return HandleIRQExit(record->ts, record->tid & 0xff, record->tid >> 8);
    case KTRACE_EVENT(TAG_SYSCALL_ENTER):
      return HandleSyscallEnter(record->ts, record->tid & 0xff,
                                record->tid >> 8);
    case KTRACE_EVENT(TAG_SYSCALL_EXIT):
      return HandleSyscallExit(record->ts, record->tid & 0xff,
                               record->tid >> 8);
    default:
      return false;
  }
}

bool Importer::ImportQuadRecord(const ktrace_rec_32b_t* record,
                                const TagInfo& tag_info) {
  FXL_VLOG(2) << "QUAD: tag=0x" << std::hex << record->tag << " ("
              << tag_info.name << "), tid=" << std::dec << record->tid
              << ", timestamp=" << record->ts << ", a=0x" << std::hex
              << record->a << ", b=0x" << record->b << ", c=0x" << record->c
              << ", d=0x" << record->d;

  switch (KTRACE_EVENT(record->tag)) {
    case KTRACE_EVENT(TAG_VERSION):
      version_ = record->a;
      return true;
    case KTRACE_EVENT(TAG_TICKS_PER_MS): {
      trace_ticks_t kernel_ticks_per_second =
          ToUInt64(record->a, record->b) * 1000u;
      trace_ticks_t user_ticks_per_second = zx_ticks_per_second();
      if (kernel_ticks_per_second != user_ticks_per_second) {
        FXL_LOG(WARNING) << "Kernel and userspace are using different tracing "
                            "timebases, "
                            "tracks may be misaligned: "
                         << "kernel_ticks_per_second="
                         << kernel_ticks_per_second
                         << "user_ticks_per_second=" << user_ticks_per_second;
      }
      return true;
    }
    case KTRACE_EVENT(TAG_PAGE_FAULT):
      return HandlePageFault(record->ts, record->d,
                             ToUInt64(record->a, record->b), record->c);
    case KTRACE_EVENT(TAG_CONTEXT_SWITCH): {
      trace_cpu_number_t cpu = record->b & 0xff;
      trace_thread_state_t outgoing_thread_state =
          ToTraceThreadState((record->b >> 8) & 0xff);
      trace_thread_priority_t outgoing_thread_priority =
          (record->b >> 16) & 0xff;
      trace_thread_priority_t incoming_thread_priority = record->b >> 24;
      return HandleContextSwitch(record->ts, cpu, outgoing_thread_state,
                                 outgoing_thread_priority,
                                 incoming_thread_priority, record->tid,
                                 record->c, record->a, record->d);
    }
    case KTRACE_EVENT(TAG_OBJECT_DELETE):
      return HandleObjectDelete(record->ts, record->tid, record->a);
    case KTRACE_EVENT(TAG_THREAD_CREATE):
      return HandleThreadCreate(record->ts, record->tid, record->a, record->b);
    case KTRACE_EVENT(TAG_THREAD_START):
      return HandleThreadStart(record->ts, record->tid, record->a);
    case KTRACE_EVENT(TAG_THREAD_EXIT):
      return HandleThreadExit(record->ts, record->tid);
    case KTRACE_EVENT(TAG_PROC_CREATE):
      return HandleProcessCreate(record->ts, record->tid, record->a);
    case KTRACE_EVENT(TAG_PROC_START):
      return HandleProcessStart(record->ts, record->tid, record->a, record->b);
    case KTRACE_EVENT(TAG_PROC_EXIT):
      return HandleProcessExit(record->ts, record->tid, record->a);
    case KTRACE_EVENT(TAG_CHANNEL_CREATE):
      return HandleChannelCreate(record->ts, record->tid, record->a, record->b,
                                 record->c);
    case KTRACE_EVENT(TAG_CHANNEL_WRITE):
      return HandleChannelWrite(record->ts, record->tid, record->a, record->b,
                                record->c);
    case KTRACE_EVENT(TAG_CHANNEL_READ):
      return HandleChannelRead(record->ts, record->tid, record->a, record->b,
                               record->c);
    case KTRACE_EVENT(TAG_PORT_WAIT):
      return HandlePortWait(record->ts, record->tid, record->a);
    case KTRACE_EVENT(TAG_PORT_WAIT_DONE):
      return HandlePortWaitDone(record->ts, record->tid, record->a, record->b);
    case KTRACE_EVENT(TAG_PORT_CREATE):
      return HandlePortCreate(record->ts, record->tid, record->a);
    case KTRACE_EVENT(TAG_PORT_QUEUE):
      return HandlePortQueue(record->ts, record->tid, record->a, record->b);
    case KTRACE_EVENT(TAG_WAIT_ONE):
      return HandleWaitOne(record->ts, record->tid, record->a, record->b,
                           ToUInt64(record->c, record->d));
    case KTRACE_EVENT(TAG_WAIT_ONE_DONE):
      return HandleWaitOneDone(record->ts, record->tid, record->a, record->b,
                               record->c);
    case KTRACE_EVENT(TAG_VCPU_ENTER):
      return HandleVcpuEnter(record->ts, record->tid);
    case KTRACE_EVENT(TAG_VCPU_EXIT):
      return HandleVcpuExit(record->ts, record->tid, record->a,
                            ToUInt64(record->b, record->c));
    case KTRACE_EVENT(TAG_VCPU_BLOCK):
      return HandleVcpuBlock(record->ts, record->tid, record->a);
    case KTRACE_EVENT(TAG_VCPU_UNBLOCK):
      return HandleVcpuUnblock(record->ts, record->tid, record->a);
    default:
      return false;
  }
}

bool Importer::ImportNameRecord(const ktrace_rec_name_t* record,
                                const TagInfo& tag_info) {
  fbl::StringPiece name(record->name,
                        strnlen(record->name, ZX_MAX_NAME_LEN - 1));
  FXL_VLOG(2) << "NAME: tag=0x" << std::hex << record->tag << " ("
              << tag_info.name << "), id=0x" << record->id << ", arg=0x"
              << record->arg << ", name='" << fbl::String(name).c_str() << "'";

  switch (KTRACE_EVENT(record->tag)) {
    case KTRACE_EVENT(TAG_KTHREAD_NAME):
      return HandleKernelThreadName(record->id, name);
    case KTRACE_EVENT(TAG_THREAD_NAME):
      return HandleThreadName(record->id, record->arg, name);
    case KTRACE_EVENT(TAG_PROC_NAME):
      return HandleProcessName(record->id, name);
    case KTRACE_EVENT(TAG_SYSCALL_NAME):
      return HandleSyscallName(record->id, name);
    case KTRACE_EVENT(TAG_IRQ_NAME):
      return HandleIRQName(record->id, name);
    case KTRACE_EVENT(TAG_PROBE_NAME):
      return HandleProbeName(record->id, name);
    case KTRACE_EVENT(TAG_VCPU_META):
      return HandleVcpuMeta(record->id, name);
    case KTRACE_EVENT(TAG_VCPU_EXIT_META):
      return HandleVcpuExitMeta(record->id, name);
    default:
      return false;
  }
}

bool Importer::ImportProbeRecord(const ktrace_header_t* record,
                                 size_t record_size) {
  if (!(KTRACE_EVENT(record->tag) & KTRACE_NAMED_EVENT_BIT)) {
    return ImportUnknownRecord(record, record_size);
  }

  const uint32_t event_name_id = KTRACE_EVENT_NAME_ID(record->tag);
  const bool cpu_trace = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_CPU;

  if (record_size == 24) {
    const auto arg0 = reinterpret_cast<const uint32_t*>(record + 1)[0];
    const auto arg1 = reinterpret_cast<const uint32_t*>(record + 1)[1];
    FXL_VLOG(2) << "PROBE: tag=0x" << std::hex << record->tag
                << ", event_name_id=0x" << event_name_id << ", tid=" << std::dec
                << record->tid << ", ts=" << record->ts << ", arg0=0x"
                << std::hex << arg0 << ", arg1=0x" << arg1;
    return HandleProbe(record->ts, record->tid, event_name_id, cpu_trace, arg0,
                       arg1);
  } else if (record_size == 32) {
    const auto arg0 = reinterpret_cast<const uint64_t*>(record + 1)[0];
    const auto arg1 = reinterpret_cast<const uint64_t*>(record + 1)[1];
    FXL_VLOG(2) << "PROBE: tag=0x" << std::hex << record->tag
                << ", event_name_id=0x" << event_name_id << ", tid=" << std::dec
                << record->tid << ", ts=" << record->ts << ", arg0=0x"
                << std::hex << arg0 << ", arg1=0x" << arg1;
    return HandleProbe(record->ts, record->tid, event_name_id, cpu_trace, arg0,
                       arg1);
  }

  FXL_VLOG(2) << "PROBE: tag=0x" << std::hex << record->tag
              << ", event_name_id=0x" << event_name_id << ", tid=" << std::dec
              << record->tid << ", ts=" << record->ts;
  return HandleProbe(record->ts, record->tid, event_name_id, cpu_trace);
}

bool Importer::ImportDurationRecord(const ktrace_header_t* record,
                                    size_t record_size) {
  if (!(KTRACE_EVENT(record->tag) & KTRACE_NAMED_EVENT_BIT)) {
    return ImportUnknownRecord(record, record_size);
  }

  const uint32_t event_name_id = KTRACE_EVENT_NAME_ID(record->tag);
  const uint32_t group = KTRACE_GROUP(record->tag);
  const bool cpu_trace = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_CPU;
  const bool is_begin = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_BEGIN;
  const bool is_end = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_END;

  if (record_size == 32) {
    const auto arg0 = reinterpret_cast<const uint64_t*>(record + 1)[0];
    const auto arg1 = reinterpret_cast<const uint64_t*>(record + 1)[1];
    if (is_begin) {
      return HandleDurationBegin(record->ts, record->tid, event_name_id, group,
                                 cpu_trace, arg0, arg1);
    } else if (is_end) {
      return HandleDurationEnd(record->ts, record->tid, event_name_id, group,
                               cpu_trace, arg0, arg1);
    }
  } else {
    if (is_begin) {
      return HandleDurationBegin(record->ts, record->tid, event_name_id, group,
                                 cpu_trace);
    } else if (is_end) {
      return HandleDurationEnd(record->ts, record->tid, event_name_id, group,
                               cpu_trace);
    }
  }

  return false;
}

bool Importer::ImportFlowRecord(const ktrace_header_t* record,
                                size_t record_size) {
  FXL_DCHECK(KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_FLOW);

  if (!(KTRACE_EVENT(record->tag) & KTRACE_NAMED_EVENT_BIT)) {
    return ImportUnknownRecord(record, record_size);
  }

  const uint32_t event_name_id = KTRACE_EVENT_NAME_ID(record->tag);
  const uint32_t group = KTRACE_GROUP(record->tag);
  const bool cpu_trace = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_CPU;
  const bool is_begin = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_BEGIN;
  const bool is_end = KTRACE_FLAGS(record->tag) & KTRACE_FLAGS_END;

  if (record_size == 32) {
    const auto flow_id = reinterpret_cast<const uint64_t*>(record + 1)[0];
    if (is_begin) {
      return HandleFlowBegin(record->ts, record->tid, event_name_id, group,
                             cpu_trace, flow_id);
    } else if (is_end) {
      return HandleFlowEnd(record->ts, record->tid, event_name_id, group,
                           cpu_trace, flow_id);
    } else {
      return ImportUnknownRecord(record, record_size);
    }
  }

  return false;
}

bool Importer::ImportUnknownRecord(const ktrace_header_t* record,
                                   size_t record_size) {
  FXL_VLOG(2) << "UNKNOWN: tag=0x" << std::hex << record->tag
              << ", size=" << std::dec << record_size;
  return false;
}

bool Importer::HandleKernelThreadName(KernelThread kernel_thread,
                                      const fbl::StringPiece& name) {
  trace_string_ref name_ref =
      trace_make_inline_string_ref(name.data(), name.length());
  trace_context_write_thread_info_record(
      context_, kNoProcess, kKernelThreadFlag | kernel_thread, &name_ref);
  kernel_thread_refs_.emplace(
      kernel_thread,
      trace_context_make_registered_thread(context_, kNoProcess,
                                           kKernelThreadFlag | kernel_thread));
  return true;
}

bool Importer::HandleThreadName(zx_koid_t thread, zx_koid_t process,
                                const fbl::StringPiece& name) {
  trace_string_ref name_ref =
      trace_make_inline_string_ref(name.data(), name.length());
  trace_context_write_thread_info_record(context_, process, thread, &name_ref);
  thread_refs_.emplace(
      thread, trace_context_make_registered_thread(context_, process, thread));
  return true;
}

bool Importer::HandleProcessName(zx_koid_t process,
                                 const fbl::StringPiece& name) {
  trace_string_ref name_ref =
      trace_make_inline_string_ref(name.data(), name.length());
  trace_context_write_process_info_record(context_, process, &name_ref);
  return true;
}

bool Importer::HandleSyscallName(uint32_t syscall,
                                 const fbl::StringPiece& name) {
  syscall_names_.emplace(syscall, trace_context_make_registered_string_copy(
                                      context_, name.data(), name.length()));
  return true;
}

bool Importer::HandleIRQName(uint32_t irq, const fbl::StringPiece& name) {
  irq_names_.emplace(irq, trace_context_make_registered_string_copy(
                              context_, name.data(), name.length()));
  return true;
}

bool Importer::HandleProbeName(uint32_t event_name_id,
                               const fbl::StringPiece& name) {
  probe_names_.emplace(event_name_id,
                       trace_context_make_registered_string_copy(
                           context_, name.data(), name.length()));
  return true;
}

bool Importer::HandleVcpuMeta(uint32_t meta, const fbl::StringPiece& name) {
  vcpu_meta_.emplace(meta, trace_context_make_registered_string_copy(
                               context_, name.data(), name.length()));
  return true;
}

bool Importer::HandleVcpuExitMeta(uint32_t exit, const fbl::StringPiece& name) {
  vcpu_exit_meta_.emplace(exit, trace_context_make_registered_string_copy(
                                    context_, name.data(), name.length()));
  return true;
}

bool Importer::HandleIRQEnter(trace_ticks_t event_time,
                              trace_cpu_number_t cpu_number, uint32_t irq) {
  trace_thread_ref_t thread_ref = GetCpuPseudoThreadRef(cpu_number);
  if (!trace_is_unknown_thread_ref(&thread_ref)) {
    trace_string_ref_t name_ref = GetNameRef(irq_names_, "irq", irq);
    trace_context_write_duration_begin_event_record(
        context_, event_time, &thread_ref, &irq_category_ref_, &name_ref,
        nullptr, 0u);
  }
  return true;
}

bool Importer::HandleIRQExit(trace_ticks_t event_time,
                             trace_cpu_number_t cpu_number, uint32_t irq) {
  trace_thread_ref_t thread_ref = GetCpuPseudoThreadRef(cpu_number);
  if (!trace_is_unknown_thread_ref(&thread_ref)) {
    trace_string_ref_t name_ref = GetNameRef(irq_names_, "irq", irq);
    trace_context_write_duration_end_event_record(
        context_, event_time, &thread_ref, &irq_category_ref_, &name_ref,
        nullptr, 0u);
  }
  return true;
}

bool Importer::HandleSyscallEnter(trace_ticks_t event_time,
                                  trace_cpu_number_t cpu_number,
                                  uint32_t syscall) {
  zx_koid_t thread = GetCpuCurrentThread(cpu_number);
  if (thread != ZX_KOID_INVALID) {
    auto& duration = syscall_durations_[thread];
    if (duration.valid) {
      FXL_LOG(WARNING) << "Syscall duration for thread " << thread
                       << " already exists";
    }
    duration =
        SyscallDuration{.begin = event_time, .syscall = syscall, .valid = true};
  }
  return true;
}

bool Importer::HandleSyscallExit(trace_ticks_t event_time,
                                 trace_cpu_number_t cpu_number,
                                 uint32_t syscall) {
  zx_koid_t thread = GetCpuCurrentThread(cpu_number);
  if (thread != ZX_KOID_INVALID) {
    auto& duration = syscall_durations_[thread];
    if (!duration.valid) {
      // This is common as syscalls that start before tracing starts will not
      // have a corresponding SyscallEnter call and should be ignored.
      return false;
    }
    if (duration.syscall != syscall) {
      FXL_LOG(WARNING) << "Syscall end type on thread " << thread
                       << " does not match the begin type";
      return false;
    }
    trace_thread_ref_t thread_ref = GetThreadRef(thread);
    trace_string_ref_t name_ref =
        GetNameRef(syscall_names_, "syscall", syscall);
    trace_context_write_duration_event_record(
        context_, duration.begin, event_time, &thread_ref,
        &syscall_category_ref_, &name_ref, nullptr, 0u);
    duration.valid = false;
  }
  return true;
}

bool Importer::HandlePageFault(trace_ticks_t event_time,
                               trace_cpu_number_t cpu_number,
                               uint64_t virtual_address, uint32_t flags) {
  trace_thread_ref_t thread_ref = GetCpuCurrentThreadRef(cpu_number);
  if (!trace_is_unknown_thread_ref(&thread_ref)) {
    trace_arg_t args[] = {
        trace_make_arg(vaddr_name_ref_,
                       trace_make_pointer_arg_value(virtual_address)),
        trace_make_arg(flags_name_ref_, trace_make_uint32_arg_value(flags))};
    trace_context_write_instant_event_record(
        context_, event_time, &thread_ref, &irq_category_ref_,
        &page_fault_name_ref_, TRACE_SCOPE_THREAD, args, fbl::count_of(args));
  }
  return true;
}

bool Importer::HandleContextSwitch(
    trace_ticks_t event_time, trace_cpu_number_t cpu_number,
    trace_thread_state_t outgoing_thread_state,
    trace_thread_priority_t outgoing_thread_priority,
    trace_thread_priority_t incoming_thread_priority, zx_koid_t outgoing_thread,
    KernelThread outgoing_kernel_thread, zx_koid_t incoming_thread,
    KernelThread incoming_kernel_thread) {
  trace_thread_ref_t outgoing_thread_ref = GetCpuCurrentThreadRef(cpu_number);
  trace_thread_ref_t incoming_thread_ref =
      incoming_thread
          ? SwitchCpuToThread(cpu_number, incoming_thread)
          : SwitchCpuToKernelThread(cpu_number, incoming_kernel_thread);
  if (!trace_is_unknown_thread_ref(&outgoing_thread_ref) ||
      !trace_is_unknown_thread_ref(&incoming_thread_ref)) {
    trace_context_write_context_switch_record(
        context_, event_time, cpu_number, outgoing_thread_state,
        &outgoing_thread_ref, &incoming_thread_ref, outgoing_thread_priority,
        incoming_thread_priority);
  }
  return true;
}

bool Importer::HandleObjectDelete(trace_ticks_t event_time, zx_koid_t thread,
                                  zx_koid_t object) {
  auto it = channels_.ids_.find(object);
  if (it != channels_.ids_.end()) {
    channels_.message_counters_.erase(it->second);
  }

  return true;
}

bool Importer::HandleThreadCreate(trace_ticks_t event_time, zx_koid_t thread,
                                  zx_koid_t affected_thread,
                                  zx_koid_t affected_process) {
  return false;
}

bool Importer::HandleThreadStart(trace_ticks_t event_time, zx_koid_t thread,
                                 zx_koid_t affected_thread) {
  return false;
}

bool Importer::HandleThreadExit(trace_ticks_t event_time, zx_koid_t thread) {
  return false;
}

bool Importer::HandleProcessCreate(trace_ticks_t event_time, zx_koid_t thread,
                                   zx_koid_t affected_process) {
  return false;
}

bool Importer::HandleProcessStart(trace_ticks_t event_time, zx_koid_t thread,
                                  zx_koid_t affected_thread,
                                  zx_koid_t affected_process) {
  return false;
}

bool Importer::HandleProcessExit(trace_ticks_t event_time, zx_koid_t thread,
                                 zx_koid_t affected_process) {
  return false;
}

bool Importer::HandleChannelCreate(trace_ticks_t event_time, zx_koid_t thread,
                                   zx_koid_t channel0, zx_koid_t channel1,
                                   uint32_t flags) {
  if (channels_.ids_.count(channel0) != 0 ||
      channels_.ids_.count(channel1) != 0) {
    FXL_LOG(WARNING)
        << "Channel creation for an already known channel was requested, "
        << "ignoring the request.";
    return false;
  }

  channels_.ids_[channel0] = channels_.ids_[channel1] = channels_.next_id_++;
  return true;
}

bool Importer::HandleChannelWrite(trace_ticks_t event_time, zx_koid_t thread,
                                  zx_koid_t channel, uint32_t num_bytes,
                                  uint32_t num_handles) {
  auto it = channels_.ids_.find(channel);
  if (it == channels_.ids_.end())
    return false;

  auto counter = std::get<Channels::kWriteCounterIndex>(
      channels_.message_counters_[it->second])++;

  trace_thread_ref_t thread_ref = GetThreadRef(thread);
  trace_arg_t args[2] = {
      trace_make_arg(num_bytes_name_ref_,
                     trace_make_uint32_arg_value(num_bytes)),
      trace_make_arg(num_handles_name_ref_,
                     trace_make_uint32_arg_value(num_handles))};
  trace_context_write_flow_begin_event_record(
      context_, event_time, &thread_ref, &channel_category_ref_,
      &channel_write_name_ref_, counter, args, fbl::count_of(args));
  return true;
}

bool Importer::HandleChannelRead(trace_ticks_t event_time, zx_koid_t thread,
                                 zx_koid_t channel, uint32_t num_bytes,
                                 uint32_t num_handles) {
  auto it = channels_.ids_.find(channel);
  if (it == channels_.ids_.end())
    return false;

  auto counter = std::get<Channels::kReadCounterIndex>(
      channels_.message_counters_[it->second])++;

  trace_thread_ref_t thread_ref = GetThreadRef(thread);
  trace_arg_t args[2] = {
      trace_make_arg(num_bytes_name_ref_,
                     trace_make_uint32_arg_value(num_bytes)),
      trace_make_arg(num_handles_name_ref_,
                     trace_make_uint32_arg_value(num_handles))};
  trace_context_write_flow_end_event_record(
      context_, event_time, &thread_ref, &channel_category_ref_,
      &channel_read_name_ref_, counter, args, fbl::count_of(args));
  return true;
}

bool Importer::HandlePortWait(trace_ticks_t event_time, zx_koid_t thread,
                              zx_koid_t port) {
  return false;
}

bool Importer::HandlePortWaitDone(trace_ticks_t event_time, zx_koid_t thread,
                                  zx_koid_t port, uint32_t status) {
  return false;
}

bool Importer::HandlePortCreate(trace_ticks_t event_time, zx_koid_t thread,
                                zx_koid_t port) {
  return false;
}

bool Importer::HandlePortQueue(trace_ticks_t event_time, zx_koid_t thread,
                               zx_koid_t port, uint32_t num_bytes) {
  return false;
}

bool Importer::HandleWaitOne(trace_ticks_t event_time, zx_koid_t thread,
                             zx_koid_t object, uint32_t signals,
                             zx_time_t timeout) {
  return false;
}

bool Importer::HandleWaitOneDone(trace_ticks_t event_time, zx_koid_t thread,
                                 zx_koid_t object, uint32_t status,
                                 uint32_t pending) {
  return false;
}

bool Importer::HandleProbe(trace_ticks_t event_time, zx_koid_t thread,
                           uint32_t event_name_id, bool cpu_trace) {
  trace_thread_ref_t thread_ref =
      cpu_trace ? GetCpuPseudoThreadRef(thread) : GetThreadRef(thread);
  trace_string_ref_t name_ref =
      GetNameRef(probe_names_, "probe", event_name_id);
  trace_context_write_instant_event_record(context_, event_time, &thread_ref,
                                           &probe_category_ref_, &name_ref,
                                           TRACE_SCOPE_THREAD, nullptr, 0u);
  return true;
}

bool Importer::HandleProbe(trace_ticks_t event_time, zx_koid_t thread,
                           uint32_t event_name_id, bool cpu_trace,
                           uint32_t arg0, uint32_t arg1) {
  trace_thread_ref_t thread_ref =
      cpu_trace ? GetCpuPseudoThreadRef(thread) : GetThreadRef(thread);
  trace_string_ref_t name_ref =
      GetNameRef(probe_names_, "probe", event_name_id);
  trace_arg_t args[] = {
      trace_make_arg(arg0_name_ref_, trace_make_uint32_arg_value(arg0)),
      trace_make_arg(arg1_name_ref_, trace_make_uint32_arg_value(arg1))};
  trace_context_write_instant_event_record(
      context_, event_time, &thread_ref, &probe_category_ref_, &name_ref,
      TRACE_SCOPE_THREAD, args, fbl::count_of(args));
  return true;
}

bool Importer::HandleProbe(trace_ticks_t event_time, zx_koid_t thread,
                           uint32_t event_name_id, bool cpu_trace,
                           uint64_t arg0, uint64_t arg1) {
  trace_thread_ref_t thread_ref =
      cpu_trace ? GetCpuPseudoThreadRef(thread) : GetThreadRef(thread);
  trace_string_ref_t name_ref =
      GetNameRef(probe_names_, "probe", event_name_id);
  trace_arg_t args[] = {
      trace_make_arg(arg0_name_ref_, trace_make_uint64_arg_value(arg0)),
      trace_make_arg(arg1_name_ref_, trace_make_uint64_arg_value(arg1))};
  trace_context_write_instant_event_record(
      context_, event_time, &thread_ref, &probe_category_ref_, &name_ref,
      TRACE_SCOPE_THREAD, args, fbl::count_of(args));
  return true;
}

bool Importer::HandleVcpuEnter(trace_ticks_t event_time, zx_koid_t thread) {
  auto& duration = vcpu_durations_[thread];
  if (duration.valid) {
    FXL_LOG(WARNING) << "VCPU duration for thread " << thread
                     << " already exists";
    return false;
  }
  duration = VcpuDuration{.begin = event_time, .valid = true};
  return true;
}

bool Importer::HandleVcpuExit(trace_ticks_t event_time, zx_koid_t thread,
                              uint32_t exit, uint64_t exit_addr) {
  auto& duration = vcpu_durations_[thread];
  trace_arg_t args[] = {
      trace_make_arg(exit_address_name_ref_,
                     trace_make_pointer_arg_value(exit_addr)),
  };
  if (!duration.valid) {
    FXL_LOG(WARNING) << "VCPU duration for thread " << thread
                     << " does not have a beginning";
    return false;
  }

  trace_thread_ref_t thread_ref = GetThreadRef(thread);
  trace_string_ref_t name_ref = GetNameRef(vcpu_exit_meta_, "exit", exit);
  trace_context_write_duration_event_record(
      context_, duration.begin, event_time, &thread_ref, &vcpu_category_ref_,
      &name_ref, args, fbl::count_of(args));

  duration.valid = false;
  return true;
}

bool Importer::HandleVcpuBlock(trace_ticks_t event_time, zx_koid_t thread,
                               uint32_t meta) {
  trace_thread_ref_t thread_ref = GetThreadRef(thread);
  trace_string_ref_t name_ref = GetNameRef(vcpu_meta_, "meta", meta);
  trace_context_write_duration_begin_event_record(
      context_, event_time, &thread_ref, &vcpu_category_ref_, &name_ref,
      nullptr, 0u);
  return true;
}

bool Importer::HandleVcpuUnblock(trace_ticks_t event_time, zx_koid_t thread,
                                 uint32_t meta) {
  trace_thread_ref_t thread_ref = GetThreadRef(thread);
  trace_string_ref_t name_ref = GetNameRef(vcpu_meta_, "meta", meta);
  trace_context_write_duration_end_event_record(
      context_, event_time, &thread_ref, &vcpu_category_ref_, &name_ref,
      nullptr, 0u);
  return true;
}

bool Importer::HandleDurationBegin(trace_ticks_t event_time, zx_koid_t thread,
                                   uint32_t event_name_id, uint32_t group,
                                   bool cpu_trace) {
  trace_thread_ref_t thread_ref =
      cpu_trace ? GetCpuPseudoThreadRef(thread) : GetThreadRef(thread);
  trace_string_ref_t name_ref =
      GetNameRef(probe_names_, "probe", event_name_id);
  trace_string_ref_t category_ref = GetCategoryForGroup(group);
  trace_context_write_duration_begin_event_record(
      context_, event_time, &thread_ref, &category_ref, &name_ref, nullptr, 0u);

  return true;
}

bool Importer::HandleDurationBegin(trace_ticks_t event_time, zx_koid_t thread,
                                   uint32_t event_name_id, uint32_t group,
                                   bool cpu_trace, uint64_t arg0,
                                   uint64_t arg1) {
  trace_thread_ref_t thread_ref =
      cpu_trace ? GetCpuPseudoThreadRef(thread) : GetThreadRef(thread);
  trace_arg_t args[] = {
      trace_make_arg(arg0_name_ref_, trace_make_uint64_arg_value(arg0)),
      trace_make_arg(arg1_name_ref_, trace_make_uint64_arg_value(arg1))};
  trace_string_ref_t name_ref =
      GetNameRef(probe_names_, "probe", event_name_id);
  trace_string_ref_t category_ref = GetCategoryForGroup(group);
  trace_context_write_duration_begin_event_record(
      context_, event_time, &thread_ref, &category_ref, &name_ref, args,
      fbl::count_of(args));

  return true;
}

bool Importer::HandleDurationEnd(trace_ticks_t event_time, zx_koid_t thread,
                                 uint32_t event_name_id, uint32_t group,
                                 bool cpu_trace) {
  trace_thread_ref_t thread_ref =
      cpu_trace ? GetCpuPseudoThreadRef(thread) : GetThreadRef(thread);
  trace_string_ref_t name_ref =
      GetNameRef(probe_names_, "probe", event_name_id);
  trace_string_ref_t category_ref = GetCategoryForGroup(group);
  trace_context_write_duration_end_event_record(
      context_, event_time, &thread_ref, &category_ref, &name_ref, nullptr, 0u);

  return true;
}

bool Importer::HandleDurationEnd(trace_ticks_t event_time, zx_koid_t thread,
                                 uint32_t event_name_id, uint32_t group,
                                 bool cpu_trace, uint64_t arg0, uint64_t arg1) {
  trace_thread_ref_t thread_ref =
      cpu_trace ? GetCpuPseudoThreadRef(thread) : GetThreadRef(thread);
  trace_arg_t args[] = {
      trace_make_arg(arg0_name_ref_, trace_make_uint64_arg_value(arg0)),
      trace_make_arg(arg1_name_ref_, trace_make_uint64_arg_value(arg1))};
  trace_string_ref_t name_ref =
      GetNameRef(probe_names_, "probe", event_name_id);
  trace_string_ref_t category_ref = GetCategoryForGroup(group);
  trace_context_write_duration_end_event_record(
      context_, event_time, &thread_ref, &category_ref, &name_ref, args,
      fbl::count_of(args));

  return true;
}

bool Importer::HandleFlowBegin(trace_ticks_t event_time, zx_koid_t thread,
                               uint32_t event_name_id, uint32_t group,
                               bool cpu_trace, trace_flow_id_t flow_id) {
  trace_thread_ref_t thread_ref =
      cpu_trace ? GetCpuPseudoThreadRef(thread) : GetThreadRef(thread);
  trace_string_ref_t name_ref =
      GetNameRef(probe_names_, "probe", event_name_id);
  trace_string_ref_t category_ref = GetCategoryForGroup(group);
  trace_context_write_flow_begin_event_record(context_, event_time, &thread_ref,
                                              &category_ref, &name_ref, flow_id,
                                              nullptr, 0u);

  return true;
}

bool Importer::HandleFlowEnd(trace_ticks_t event_time, zx_koid_t thread,
                             uint32_t event_name_id, uint32_t group,
                             bool cpu_trace, trace_flow_id_t flow_id) {
  trace_thread_ref_t thread_ref =
      cpu_trace ? GetCpuPseudoThreadRef(thread) : GetThreadRef(thread);
  trace_string_ref_t name_ref =
      GetNameRef(probe_names_, "probe", event_name_id);
  trace_string_ref_t category_ref = GetCategoryForGroup(group);
  trace_context_write_flow_end_event_record(context_, event_time, &thread_ref,
                                            &category_ref, &name_ref, flow_id,
                                            nullptr, 0u);

  return true;
}

trace_thread_ref_t Importer::GetCpuCurrentThreadRef(
    trace_cpu_number_t cpu_number) {
  if (cpu_number >= cpu_infos_.size())
    return kUnknownThreadRef;
  return cpu_infos_[cpu_number].current_thread_ref;
}

zx_koid_t Importer::GetCpuCurrentThread(trace_cpu_number_t cpu_number) {
  if (cpu_number >= cpu_infos_.size())
    return ZX_KOID_INVALID;
  return cpu_infos_[cpu_number].current_thread;
}

trace_thread_ref_t Importer::SwitchCpuToThread(trace_cpu_number_t cpu_number,
                                               zx_koid_t thread) {
  if (cpu_number >= cpu_infos_.size())
    cpu_infos_.resize(cpu_number + 1u);
  cpu_infos_[cpu_number].current_thread = thread;
  return cpu_infos_[cpu_number].current_thread_ref = GetThreadRef(thread);
}

trace_thread_ref_t Importer::SwitchCpuToKernelThread(
    trace_cpu_number_t cpu_number, KernelThread kernel_thread) {
  if (cpu_number >= cpu_infos_.size())
    cpu_infos_.resize(cpu_number + 1u);
  cpu_infos_[cpu_number].current_thread = kernel_thread;
  return cpu_infos_[cpu_number].current_thread_ref =
             GetKernelThreadRef(kernel_thread);
}

const trace_string_ref_t& Importer::GetNameRef(
    std::unordered_map<uint32_t, trace_string_ref_t>& table, const char* kind,
    uint32_t id) {
  auto it = table.find(id);
  if (it == table.end()) {
    fbl::String name = fbl::StringPrintf("%s %#x", kind, id);
    std::tie(it, std::ignore) =
        table.emplace(id, trace_context_make_registered_string_copy(
                              context_, name.data(), name.length()));
  }
  return it->second;
}

const trace_thread_ref_t& Importer::GetThreadRef(zx_koid_t thread) {
  // |trace_make_inline_thread_ref()| requires a valid thread id (given that
  // we're using ZX_KOID_INVALID for the process for unknown threads).
  if (thread == ZX_KOID_INVALID) {
    return kUnknownThreadRef;
  }
  auto it = thread_refs_.find(thread);
  if (it == thread_refs_.end()) {
    std::tie(it, std::ignore) = thread_refs_.emplace(
        thread, trace_make_inline_thread_ref(kNoProcess, thread));
  }
  return it->second;
}

// TODO(TO-106): Revisit using pseudo thread references to support per-CPU
// events.
const trace_thread_ref_t& Importer::GetCpuPseudoThreadRef(
    trace_cpu_number_t cpu) {
  const zx_koid_t thread = kKernelPseudoCpuBase + cpu;
  auto it = thread_refs_.find(thread);
  if (it == thread_refs_.end()) {
    fbl::String label = fbl::StringPrintf("cpu-%d", cpu);

    trace_string_ref name_ref =
        trace_make_inline_string_ref(label.data(), label.length());
    trace_context_write_thread_info_record(context_, kNoProcess, thread,
                                           &name_ref);
    std::tie(it, std::ignore) = thread_refs_.emplace(
        thread,
        trace_context_make_registered_thread(context_, kNoProcess, thread));
  }
  return it->second;
}

const trace_thread_ref_t& Importer::GetKernelThreadRef(
    KernelThread kernel_thread) {
  auto it = kernel_thread_refs_.find(kernel_thread);
  if (it == kernel_thread_refs_.end()) {
    std::tie(it, std::ignore) = kernel_thread_refs_.emplace(
        kernel_thread, trace_make_inline_thread_ref(
                           kNoProcess, kKernelThreadFlag | kernel_thread));
  }
  return it->second;
}

const trace_string_ref_t& Importer::GetCategoryForGroup(uint32_t group) {
  switch (group) {
    case KTRACE_GRP_META:
      return meta_category_ref_;
    case KTRACE_GRP_LIFECYCLE:
      return lifecycle_category_ref_;
    case KTRACE_GRP_SCHEDULER:
      return sched_category_ref_;
    case KTRACE_GRP_TASKS:
      return tasks_category_ref_;
    case KTRACE_GRP_IPC:
      return ipc_category_ref_;
    case KTRACE_GRP_IRQ:
      return irq_category_ref_;
    case KTRACE_GRP_PROBE:
      return probe_category_ref_;
    case KTRACE_GRP_ARCH:
      return arch_category_ref_;
    default:
      return unknown_category_ref_;
  }
}

}  // namespace ktrace_provider
