// 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 "lib/fxl/logging.h"
#include "lib/fxl/time/time_point.h"

namespace ktrace_provider {
namespace {

constexpr zx_koid_t kNoProcess = 0u;
constexpr zx_koid_t kKernelThreadFlag = 0x100000000;
constexpr uint32_t kProbeFlag = 0x800;

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")),
      ipc_category_ref_(MAKE_STRING("kernel:ipc")),
      irq_category_ref_(MAKE_STRING("kernel:irq")),
      probe_category_ref_(MAKE_STRING("kernel:probe")),
      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")) {}

#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=" << record->tag;
      }
    } else {
      break;
    }
  }

  FXL_VLOG(2) << "Import of ktrace records 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);
    }
  }

  if (KTRACE_EVENT(record->tag) & kProbeFlag)
    return ImportProbeRecord(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) {
  uint32_t probe = KTRACE_EVENT(record->tag) & 0x7ff;
  if (record_size >= 24) {
    uint32_t arg0 = reinterpret_cast<const uint32_t*>(record + 1)[0];
    uint32_t arg1 = reinterpret_cast<const uint32_t*>(record + 1)[1];
    FXL_VLOG(2) << "PROBE: tag=0x" << std::hex << record->tag << ", probe=0x"
                << probe << ", tid=" << std::dec << record->tid
                << ", ts=" << record->ts << ", arg0=0x" << std::hex << arg0
                << ", arg1=0x" << arg1;
    return HandleProbe(record->ts, record->tid, probe, arg0, arg1);
  }

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

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 probe, const fbl::StringPiece& name) {
  probe_names_.emplace(probe, 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 = GetCpuCurrentThreadRef(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 = GetCpuCurrentThreadRef(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 probe) {
  trace_thread_ref_t thread_ref = GetThreadRef(thread);
  trace_string_ref_t name_ref = GetNameRef(probe_names_, "probe", probe);
  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 probe, uint32_t arg0, uint32_t arg1) {
  trace_thread_ref_t thread_ref = GetThreadRef(thread);
  trace_string_ref_t name_ref = GetNameRef(probe_names_, "probe", probe);
  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::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;
}

trace_thread_ref_t Importer::GetCpuCurrentThreadRef(
    trace_cpu_number_t cpu_number) {
  if (cpu_number >= cpu_infos_.size())
    return trace_make_unknown_thread_ref();
  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) {
  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;
}

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;
}

}  // namespace ktrace_provider
