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

use {
    fuchsia_zircon as zx,
    pin_project::pin_project,
    std::{ffi::CStr, future::Future, marker::PhantomData, mem, pin::Pin, ptr, task::Poll},
};

pub use sys::{TRACE_BLOB_TYPE_DATA, TRACE_BLOB_TYPE_LAST_BRANCH, TRACE_BLOB_TYPE_PERFETTO};

/// `Scope` represents the scope of a trace event.
#[derive(Copy, Clone)]
pub enum Scope {
    Thread,
    Process,
    Global,
}

impl Scope {
    fn into_raw(self) -> sys::trace_scope_t {
        match self {
            Scope::Thread => sys::TRACE_SCOPE_THREAD,
            Scope::Process => sys::TRACE_SCOPE_PROCESS,
            Scope::Global => sys::TRACE_SCOPE_GLOBAL,
        }
    }
}

/// Returns true if tracing is enabled.
#[inline]
pub fn is_enabled() -> bool {
    // Trivial no-argument function that will not race
    unsafe { sys::trace_state() != sys::TRACE_STOPPED }
}

/// Returns true if tracing has been enabled for the given category.
pub fn category_enabled(category: &'static CStr) -> bool {
    // Function requires a pointer to a static null-terminated string literal,
    // which `&'static CStr` is.
    unsafe { sys::trace_is_category_enabled(category.as_ptr()) }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TraceState {
    Stopped,
    Started,
    Stopping,
}

pub fn trace_state() -> TraceState {
    match unsafe { sys::trace_state() } {
        sys::TRACE_STOPPED => TraceState::Stopped,
        sys::TRACE_STARTED => TraceState::Started,
        sys::TRACE_STOPPING => TraceState::Stopping,
        s => panic!("Unknown trace state {:?}", s),
    }
}

/// An identifier for flows and async spans.
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Id(u64);

impl Id {
    /// Creates a new `Id`. `Id`s created by separate calls to `new` in the same process are
    /// guaranteed to be distinct.
    pub fn new() -> Self {
        // Trivial no-argument function that cannot race.
        Self(unsafe { sys::trace_generate_nonce() })
    }

    /// Creates a new `Id` based on the current montonic time and a random `u16` to, with high
    /// probability, avoid the bug where UIs group async durations with the same trace id but
    /// different process ids.
    /// `Id::new` is likely to hit the UI bug because it (per process) generates trace ids
    /// consecutively starting from 1.
    /// https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/system/ulib/trace-engine/nonce.cc;l=15-17;drc=b1c2f508a59e6c87c617852ed3e424693a392646
    /// TODO(https://fxbug.dev/42054669) Delete this and migrate clients to `Id::new` once UIs stop grouping
    /// async durations with the same trace id but different process ids.
    pub fn random() -> Self {
        let ts = zx::Time::get_monotonic().into_nanos() as u64;
        let high_order = ts << 16;
        let low_order = rand::random::<u16>() as u64;
        Self(high_order | low_order)
    }
}

impl From<u64> for Id {
    fn from(u: u64) -> Self {
        Self(u)
    }
}

impl From<Id> for u64 {
    fn from(id: Id) -> Self {
        id.0
    }
}

#[allow(dead_code)] // TODO(https://fxbug.dev/318827209)
/// `Arg` holds an argument to a tracing function, which can be one of many types.
#[repr(transparent)]
pub struct Arg<'a>(sys::trace_arg_t, PhantomData<&'a ()>);

/// A trait for types that can be the values of an argument set.
///
/// This trait is not implementable by users of the library.
/// Users should instead use one of the common types which implements
/// `ArgValue`, such as `i32`, `f64`, or `&str`.
pub trait ArgValue {
    fn of<'a>(key: &'a str, value: Self) -> Arg<'a>
    where
        Self: 'a;
}

// Implements `arg_from` for many types.
// $valname is the name to which to bind the `Self` value in the $value expr
// $ty is the type
// $tag is the union tag indicating the variant of trace_arg_union_t being used
// $value is the union value for that particular type
macro_rules! arg_from {
    ($valname:ident, $(($type:ty, $tag:expr, $value:expr))*) => {
        $(
            impl ArgValue for $type {
                #[inline]
                fn of<'a>(key: &'a str, $valname: Self) -> Arg<'a>
                    where Self: 'a
                {
                    #[allow(unused)]
                    let $valname = $valname;

                    Arg(sys::trace_arg_t {
                        name_ref: trace_make_inline_string_ref(key),
                        value: sys::trace_arg_value_t {
                            type_: $tag,
                            value: $value,
                        },
                    }, PhantomData)
                }
            }
        )*
    }
}

// Implement ArgFrom for a variety of types
#[rustfmt::skip]
arg_from!(val,
    ((), sys::TRACE_ARG_NULL, sys::trace_arg_union_t { int32_value: 0 })
    (bool, sys::TRACE_ARG_BOOL, sys::trace_arg_union_t { bool_value: val })
    (i32, sys::TRACE_ARG_INT32, sys::trace_arg_union_t { int32_value: val })
    (u32, sys::TRACE_ARG_UINT32, sys::trace_arg_union_t { uint32_value: val })
    (i64, sys::TRACE_ARG_INT64, sys::trace_arg_union_t { int64_value: val })
    (u64, sys::TRACE_ARG_UINT64, sys::trace_arg_union_t { uint64_value: val })
    (isize, sys::TRACE_ARG_INT64, sys::trace_arg_union_t { int64_value: val as i64 })
    (usize, sys::TRACE_ARG_UINT64, sys::trace_arg_union_t { uint64_value: val as u64 })
    (f64, sys::TRACE_ARG_DOUBLE, sys::trace_arg_union_t { double_value: val })
    (zx::Koid, sys::TRACE_ARG_KOID, sys::trace_arg_union_t { koid_value: val.raw_koid() })
);

impl<T> ArgValue for *const T {
    #[inline]
    fn of<'a>(key: &'a str, val: Self) -> Arg<'a>
    where
        Self: 'a,
    {
        Arg(
            sys::trace_arg_t {
                name_ref: trace_make_inline_string_ref(key),
                value: sys::trace_arg_value_t {
                    type_: sys::TRACE_ARG_POINTER,
                    value: sys::trace_arg_union_t { pointer_value: val as usize },
                },
            },
            PhantomData,
        )
    }
}

impl<T> ArgValue for *mut T {
    #[inline]
    fn of<'a>(key: &'a str, val: Self) -> Arg<'a>
    where
        Self: 'a,
    {
        Arg(
            sys::trace_arg_t {
                name_ref: trace_make_inline_string_ref(key),
                value: sys::trace_arg_value_t {
                    type_: sys::TRACE_ARG_POINTER,
                    value: sys::trace_arg_union_t { pointer_value: val as usize },
                },
            },
            PhantomData,
        )
    }
}

impl<'a> ArgValue for &'a str {
    #[inline]
    fn of<'b>(key: &'b str, val: Self) -> Arg<'b>
    where
        Self: 'b,
    {
        Arg(
            sys::trace_arg_t {
                name_ref: trace_make_inline_string_ref(key),
                value: sys::trace_arg_value_t {
                    type_: sys::TRACE_ARG_STRING,
                    value: sys::trace_arg_union_t {
                        string_value_ref: trace_make_inline_string_ref(val),
                    },
                },
            },
            PhantomData,
        )
    }
}

/// Convenience macro for the `instant` function.
///
/// Example:
///
/// ```rust
/// instant!(c"foo", c"bar", Scope::Process, "x" => 5, "y" => "boo");
/// ```
///
/// is equivalent to
///
/// ```rust
/// instant(c"foo", c"bar", Scope::Process,
///     &[ArgValue::of("x", 5), ArgValue::of("y", "boo")]);
/// ```
/// or
/// ```rust
/// const FOO: &'static CStr = c"foo";
/// const BAR: &'static CStr = c"bar";
/// instant(FOO, BAR, Scope::Process,
///     &[ArgValue::of("x", 5), ArgValue::of("y", "boo")]);
/// ```
#[macro_export]
macro_rules! instant {
    ($category:expr, $name:expr, $scope:expr $(, $key:expr => $val:expr)*) => {
        if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            $crate::instant(&context, $name, $scope, &[$($crate::ArgValue::of($key, $val)),*]);
        }
    }
}

/// Writes an instant event representing a single moment in time.
/// The number of `args` must not be greater than 15.
#[inline]
pub fn instant(
    context: &TraceCategoryContext,
    name: &'static CStr,
    scope: Scope,
    args: &[Arg<'_>],
) {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    let name_ref = context.register_string_literal(name);
    context.write_instant(name_ref, scope, args);
}

/// Convenience macro for the `alert` function.
///
/// Example:
///
/// ```rust
/// alert!(c"foo", c"bar");
/// ```
///
/// is equivalent to
///
/// ```rust
/// alert(c"foo", c"bar");
/// ```
#[macro_export]
macro_rules! alert {
    ($category:expr, $name:expr) => {
        $crate::alert($category, $name)
    };
}

/// Sends an alert, which can be mapped to an action.
pub fn alert(category: &'static CStr, name: &'static CStr) {
    // trace_context_write_xxx functions require that:
    // - category and name are static null-terminated strings (`&'static CStr).
    // - the refs must be valid for the given call
    unsafe {
        let mut category_ref = mem::MaybeUninit::<sys::trace_string_ref_t>::uninit();
        let context =
            sys::trace_acquire_context_for_category(category.as_ptr(), category_ref.as_mut_ptr());
        if context != ptr::null() {
            sys::trace_context_send_alert(context, name.as_ptr());
            sys::trace_release_context(context);
        }
    }
}

/// Convenience macro for the `counter` function.
///
/// Example:
///
/// ```rust
/// let id = 555;
/// counter!(c"foo", c"bar", id, "x" => 5, "y" => 10);
/// ```
///
/// is equivalent to
///
/// ```rust
/// let id = 555;
/// counter(c"foo", c"bar", id,
///     &[ArgValue::of("x", 5), ArgValue::of("y", 10)]);
/// ```
#[macro_export]
macro_rules! counter {
    ($category:expr, $name:expr, $counter_id:expr $(, $key:expr => $val:expr)*) => {
        if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            $crate::counter(&context, $name, $counter_id,
                &[$($crate::ArgValue::of($key, $val)),*])
        }
    }
}

/// Writes a counter event with the specified id.
///
/// The arguments to this event are numeric samples and are typically
/// represented by the visualizer as a stacked area chart. The id serves to
/// distinguish multiple instances of counters which share the same category
/// and name within the same process.
///
/// 1 to 15 numeric arguments can be associated with an event, each of which is
/// interpreted as a distinct time series.
pub fn counter(
    context: &TraceCategoryContext,
    name: &'static CStr,
    counter_id: u64,
    args: &[Arg<'_>],
) {
    assert!(args.len() >= 1, "trace counter args must include at least one numeric argument");
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    let name_ref = context.register_string_literal(name);
    context.write_counter(name_ref, counter_id, args);
}

/// The scope of a duration event, returned by the `duration` function and the `duration!` macro.
/// The duration will be `end'ed` when this object is dropped.
#[must_use = "DurationScope must be `end`ed to be recorded"]
pub struct DurationScope<'a> {
    category: &'static CStr,
    name: &'static CStr,
    args: &'a [Arg<'a>],
    start_time: sys::trace_ticks_t,
}

impl<'a> DurationScope<'a> {
    /// Starts a new duration scope that starts now and will be end'ed when
    /// this object is dropped.
    pub fn begin(category: &'static CStr, name: &'static CStr, args: &'a [Arg<'_>]) -> Self {
        let start_time = zx::ticks_get();
        Self { category, name, args, start_time }
    }
}

impl<'a> Drop for DurationScope<'a> {
    fn drop(&mut self) {
        if let Some(context) = TraceCategoryContext::acquire(self.category) {
            let name_ref = context.register_string_literal(self.name);
            context.write_duration(name_ref, self.start_time, self.args);
        }
    }
}

/// Write a "duration complete" record representing both the beginning and end of a duration.
pub fn complete_duration(
    category: &'static CStr,
    name: &'static CStr,
    start_time: sys::trace_ticks_t,
    args: &[Arg<'_>],
) {
    if let Some(context) = TraceCategoryContext::acquire(category) {
        let name_ref = context.register_string_literal(name);
        context.write_duration(name_ref, start_time, args);
    }
}

/// Convenience macro for the `duration` function that can be used to trace
/// the duration of a scope. If you need finer grained control over when a
/// duration starts and stops, see `duration_begin` and `duration_end`.
///
/// Example:
///
/// ```rust
///   {
///       duration!(c"foo", c"bar", "x" => 5, "y" => 10);
///       ...
///       ...
///       // event will be recorded on drop.
///   }
/// ```
///
/// is equivalent to
///
/// ```rust
///   {
///       let args = [ArgValue::of("x", 5), ArgValue::of("y", 10)];
///       let _scope = duration(c"foo", c"bar", &args);
///       ...
///       ...
///       // event will be recorded on drop.
///   }
/// ```
#[macro_export]
macro_rules! duration {
    ($category:expr, $name:expr $(, $key:expr => $val:expr)* $(,)?) => {
        let mut args;
        let _scope = if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            args = [$($crate::ArgValue::of($key, $val)),*];
            Some($crate::duration($category, $name, &args))
        } else {
            None
        };
    }
}

/// Writes a duration event which ends when the current scope exits, or the
/// `end` method is manually called.
///
/// Durations describe work which is happening synchronously on one thread.
/// They can be nested to represent a control flow stack.
///
/// 0 to 15 arguments can be associated with the event, each of which is used
/// to annotate the duration with additional information.
pub fn duration<'a>(
    category: &'static CStr,
    name: &'static CStr,
    args: &'a [Arg<'_>],
) -> DurationScope<'a> {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");
    DurationScope::begin(category, name, args)
}

/// Convenience macro for the `duration_begin` function.
///
/// Examples:
///
/// ```rust
/// duration_begin!(c"foo", c"bar", "x" => 5, "y" => "boo");
/// ```
///
/// ```rust
/// const FOO: &'static CStr = c"foo";
/// const BAR: &'static CStr = c"bar";
/// duration_begin!(FOO, BAR, "x" => 5, "y" => "boo");
/// ```
#[macro_export]
macro_rules! duration_begin {
    ($category:expr, $name:expr $(, $key:expr => $val:expr)* $(,)?) => {
        if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            $crate::duration_begin(&context, $name,
                                   &[$($crate::ArgValue::of($key, $val)),*])
        }
    };
}

/// Convenience macro for the `duration_end` function.
///
/// Examples:
///
/// ```rust
/// duration_end!(c"foo", c"bar", "x" => 5, "y" => "boo");
/// ```
///
/// ```rust
/// const FOO: &'static CStr = c"foo";
/// const BAR: &'static CStr = c"bar";
/// duration_end!(FOO, BAR, "x" => 5, "y" => "boo");
/// ```
#[macro_export]
macro_rules! duration_end {
    ($category:expr, $name:expr $(, $key:expr => $val:expr)* $(,)?) => {
        if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            $crate::duration_end(&context, $name, &[$($crate::ArgValue::of($key, $val)),*])
        }
    };
}

/// Writes a duration begin event only.
/// This event must be matched by a duration end event with the same category and name.
///
/// Durations describe work which is happening synchronously on one thread.
/// They can be nested to represent a control flow stack.
///
/// 0 to 15 arguments can be associated with the event, each of which is used
/// to annotate the duration with additional information.  The arguments provided
/// to matching duration begin and duration end events are combined together in
/// the trace; it is not necessary to repeat them.
pub fn duration_begin(context: &TraceCategoryContext, name: &'static CStr, args: &[Arg<'_>]) {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    let name_ref = context.register_string_literal(name);
    context.write_duration_begin(name_ref, args);
}

/// Writes a duration end event only.
///
/// Durations describe work which is happening synchronously on one thread.
/// They can be nested to represent a control flow stack.
///
/// 0 to 15 arguments can be associated with the event, each of which is used
/// to annotate the duration with additional information.  The arguments provided
/// to matching duration begin and duration end events are combined together in
/// the trace; it is not necessary to repeat them.
pub fn duration_end(context: &TraceCategoryContext, name: &'static CStr, args: &[Arg<'_>]) {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    let name_ref = context.register_string_literal(name);
    context.write_duration_end(name_ref, args);
}

/// AsyncScope maintains state around the context of async events generated via the
/// async_enter! macro.
#[must_use = "emits an end event when dropped, so if dropped immediately creates an essentially \
              zero length duration that should just be an instant instead"]
pub struct AsyncScope {
    // AsyncScope::end uses std::mem::forget to bypass AsyncScope's Drop impl, so if any fields
    // with Drop impls are added, AsyncScope::end should be updated.
    id: Id,
    category: &'static CStr,
    name: &'static CStr,
}
impl AsyncScope {
    /// Starts a new async event scope, generating a begin event now, and ended when the
    /// object is dropped.
    pub fn begin(id: Id, category: &'static CStr, name: &'static CStr, args: &[Arg<'_>]) -> Self {
        async_begin(id, category, name, args);
        Self { id, category, name }
    }

    /// Manually end the async event scope with `args` instead of waiting until the guard is
    /// dropped (which would end the event scope with an empty `args`).
    pub fn end(self, args: &[Arg<'_>]) {
        let Self { id, category, name } = self;
        async_end(id, category, name, args);
        std::mem::forget(self);
    }
}

impl Drop for AsyncScope {
    fn drop(&mut self) {
        // AsyncScope::end uses std::mem::forget to bypass this Drop impl (to avoid emitting
        // extraneous end events), so any logic added to this Drop impl (or any fields added to
        // AsyncScope that have Drop impls) should addressed (if necessary) in AsyncScope::end.
        let Self { id, category, name } = *self;
        async_end(id, category, name, &[]);
    }
}

/// Writes an async event which ends when the current scope exits, or the `end` method is is
/// manually called.
///
/// Async events describe concurrently-scheduled work items that may migrate between threads. They
/// may be nested by sharing id, and are otherwise differentiated by their id.
///
/// 0 to 15 arguments can be associated with the event, each of which is used to annotate the
/// duration with additional information.
pub fn async_enter(
    id: Id,
    category: &'static CStr,
    name: &'static CStr,
    args: &[Arg<'_>],
) -> AsyncScope {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");
    AsyncScope::begin(id, category, name, args)
}

/// Convenience macro for the `async_enter` function, which can be used to trace the duration of a
/// scope containing async code. This macro returns the drop guard, which the caller may then
/// choose to manage.
///
/// Example:
///
/// ```rust
/// {
///     let id = Id::new();
///     let _guard = async_enter!(id, c"foo", c"bar", "x" => 5, "y" => 10);
///     ...
///     ...
///     // event recorded on drop
/// }
/// ```
///
/// is equivalent to
///
/// ```rust
/// {
///     let id = Id::new();
///     let _guard = AsyncScope::begin(id, c"foo", c"bar", &[ArgValue::of("x", 5),
///         ArgValue::of("y", 10)]);
///     ...
///     ...
///     // event recorded on drop
/// }
/// ```
///
/// Calls to async_enter! may be nested.
#[macro_export]
macro_rules! async_enter {
    ($id:expr, $category:expr, $name:expr $(, $key:expr => $val:expr)*) => {
        if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            Some($crate::AsyncScope::begin($id, $category, $name, &[$($crate::ArgValue::of($key, $val)),*]))
        } else {
            None
        }
    }
}

/// Convenience macro for the `async_instant` function, which can be used to emit an async instant
/// event.
///
/// Example:
///
/// ```rust
/// {
///     let id = Id::new();
///     async_instant!(id, c"foo", c"bar", "x" => 5, "y" => 10);
/// }
/// ```
///
/// is equivalent to
///
/// ```rust
/// {
///     let id = Id::new();
///     async_instant(
///         id, c"foo", c"bar",
///         &[ArgValue::of(c"x", 5), ArgValue::of("y", 10)]
///     );
/// }
/// ```
#[macro_export]
macro_rules! async_instant {
    ($id:expr, $category:expr, $name:expr $(, $key:expr => $val:expr)*) => {
        if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            $crate::async_instant($id, &context, $name, &[$($crate::ArgValue::of($key, $val)),*]);
        }
    }
}

/// Writes an async begin event. This event must be matched by an async end event with the same
/// id, category, and name. This function is intended to be called through use of the
/// `async_enter!` macro.
///
/// Async events describe concurrent work that may or may not migrate threads, or be otherwise
/// interleaved with other work on the same thread. They can be nested to represent a control
/// flow stack.
///
/// 0 to 15 arguments can be associated with the event, each of which is used to annotate the
/// async event with additional information. Arguments provided in matching async begin and end
/// events are combined together in the trace; it is not necessary to repeat them.
pub fn async_begin(id: Id, category: &'static CStr, name: &'static CStr, args: &[Arg<'_>]) {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    if let Some(context) = TraceCategoryContext::acquire(category) {
        let name_ref = context.register_string_literal(name);
        context.write_async_begin(id, name_ref, args);
    }
}

/// Writes an async end event. This event must be associated with a prior async begin event
/// with the same id, category, and name. This function is intended to be called implicitly
/// when the `AsyncScope` object created through use of the `async_enter!` macro is dropped.
///
/// Async events describe concurrent work that may or may not migrate threads, or be otherwise
/// interleaved with other work on the same thread. They can be nested to represent a control
/// flow stack.
///
/// 0 to 15 arguments can be associated with the event, each of which is used to annotate the
/// async event with additional information. Arguments provided in matching async begin and end
/// events are combined together in the trace; it is not necessary to repeat them.
pub fn async_end(id: Id, category: &'static CStr, name: &'static CStr, args: &[Arg<'_>]) {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    if let Some(context) = TraceCategoryContext::acquire(category) {
        let name_ref = context.register_string_literal(name);
        context.write_async_end(id, name_ref, args);
    }
}

/// Writes an async instant event with the specified id.
///
/// Asynchronous events describe work that is happening asynchronously and that
/// may span multiple threads.  Asynchronous events do not nest.  The id serves
/// to correlate the progress of distinct asynchronous operations that share
/// the same category and name within the same process.
///
/// 0 to 15 arguments can be associated with the event, each of which is used
/// to annotate the asynchronous operation with additional information.  The
/// arguments provided to matching async begin, async instant, and async end
/// events are combined together in the trace; it is not necessary to repeat them.
pub fn async_instant(
    id: Id,
    context: &TraceCategoryContext,
    name: &'static CStr,
    args: &[Arg<'_>],
) {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    let name_ref = context.register_string_literal(name);
    context.write_async_instant(id, name_ref, args);
}

#[macro_export]
macro_rules! blob {
    ($category:expr, $name:expr, $bytes:expr $(, $key:expr => $val:expr)*) => {
    if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
        $crate::blob_fn(&context, $name, $bytes, &[$($crate::ArgValue::of($key, $val)),*])
    }
    }
}
pub fn blob_fn(
    context: &TraceCategoryContext,
    name: &'static CStr,
    bytes: &[u8],
    args: &[Arg<'_>],
) {
    let name_ref = context.register_string_literal(name);
    context.write_blob(name_ref, bytes, args);
}

/// Convenience macro for the `flow_begin` function.
///
/// Example:
///
/// ```rust
/// let flow_id = 1234;
/// flow_begin!(c"foo", c"bar", flow_id, "x" => 5, "y" => "boo");
/// ```
///
/// ```rust
/// const FOO: &'static CStr = c"foo";
/// const BAR: &'static CStr = c"bar";
/// flow_begin!(c"foo", c"bar", flow_id);
/// ```
#[macro_export]
macro_rules! flow_begin {
    ($category:expr, $name:expr, $flow_id:expr $(, $key:expr => $val:expr)*) => {
        if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            $crate::flow_begin(&context, $name, $flow_id,
                               &[$($crate::ArgValue::of($key, $val)),*])
        }
    }
}

/// Convenience macro for the `flow_step` function.
///
/// Example:
///
/// ```rust
/// let flow_id = 1234;
/// flow_step!(c"foo", c"bar", flow_id, "x" => 5, "y" => "boo");
/// ```
///
/// ```rust
/// const FOO: &'static CStr = c"foo";
/// const BAR: &'static CStr = c"bar";
/// flow_step!(c"foo", c"bar", flow_id);
/// ```
#[macro_export]
macro_rules! flow_step {
    ($category:expr, $name:expr, $flow_id:expr $(, $key:expr => $val:expr)*) => {
        if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            $crate::flow_step(&context, $name, $flow_id,
                              &[$($crate::ArgValue::of($key, $val)),*])
        }
    }
}

/// Convenience macro for the `flow_end` function.
///
/// Example:
///
/// ```rust
/// let flow_id = 1234;
/// flow_end!(c"foo", c"bar", flow_id, "x" => 5, "y" => "boo");
/// ```
///
/// ```rust
/// const FOO: &'static CStr = c"foo";
/// const BAR: &'static CStr = c"bar";
/// flow_end!(c"foo", c"bar", flow_id);
/// ```
#[macro_export]
macro_rules! flow_end {
    ($category:expr, $name:expr, $flow_id:expr $(, $key:expr => $val:expr)*) => {
        if let Some(context) = $crate::TraceCategoryContext::acquire($category) {
            $crate::flow_end(&context, $name, $flow_id,
                             &[$($crate::ArgValue::of($key, $val)),*])
        }
    }
}

/// Writes a flow begin event with the specified id.
/// This event may be followed by flow steps events and must be matched by
/// a flow end event with the same category, name, and id.
///
/// Flow events describe control flow handoffs between threads or across processes.
/// They are typically represented as arrows in a visualizer.  Flow arrows are
/// from the end of the duration event which encloses the beginning of the flow
/// to the beginning of the duration event which encloses the next step or the
/// end of the flow.  The id serves to correlate flows which share the same
/// category and name across processes.
///
/// This event must be enclosed in a duration event which represents where
/// the flow handoff occurs.
///
/// 0 to 15 arguments can be associated with the event, each of which is used
/// to annotate the flow with additional information.  The arguments provided
/// to matching flow begin, flow step, and flow end events are combined together
/// in the trace; it is not necessary to repeat them.
pub fn flow_begin(
    context: &TraceCategoryContext,
    name: &'static CStr,
    flow_id: Id,
    args: &[Arg<'_>],
) {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    let name_ref = context.register_string_literal(name);
    context.write_flow_begin(name_ref, flow_id, args);
}

/// Writes a flow end event with the specified id.
///
/// Flow events describe control flow handoffs between threads or across processes.
/// They are typically represented as arrows in a visualizer.  Flow arrows are
/// from the end of the duration event which encloses the beginning of the flow
/// to the beginning of the duration event which encloses the next step or the
/// end of the flow.  The id serves to correlate flows which share the same
/// category and name across processes.
///
/// This event must be enclosed in a duration event which represents where
/// the flow handoff occurs.
///
/// 0 to 15 arguments can be associated with the event, each of which is used
/// to annotate the flow with additional information.  The arguments provided
/// to matching flow begin, flow step, and flow end events are combined together
/// in the trace; it is not necessary to repeat them.
pub fn flow_end(
    context: &TraceCategoryContext,
    name: &'static CStr,
    flow_id: Id,
    args: &[Arg<'_>],
) {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    let name_ref = context.register_string_literal(name);
    context.write_flow_end(name_ref, flow_id, args);
}

/// Writes a flow step event with the specified id.
///
/// Flow events describe control flow handoffs between threads or across processes.
/// They are typically represented as arrows in a visualizer.  Flow arrows are
/// from the end of the duration event which encloses the beginning of the flow
/// to the beginning of the duration event which encloses the next step or the
/// end of the flow.  The id serves to correlate flows which share the same
/// category and name across processes.
///
/// This event must be enclosed in a duration event which represents where
/// the flow handoff occurs.
///
/// 0 to 15 arguments can be associated with the event, each of which is used
/// to annotate the flow with additional information.  The arguments provided
/// to matching flow begin, flow step, and flow end events are combined together
/// in the trace; it is not necessary to repeat them.
pub fn flow_step(
    context: &TraceCategoryContext,
    name: &'static CStr,
    flow_id: Id,
    args: &[Arg<'_>],
) {
    assert!(args.len() <= 15, "no more than 15 trace arguments are supported");

    let name_ref = context.register_string_literal(name);
    context.write_flow_step(name_ref, flow_id, args);
}

// translated from trace-engine/types.h for inlining
const fn trace_make_empty_string_ref() -> sys::trace_string_ref_t {
    sys::trace_string_ref_t {
        encoded_value: sys::TRACE_ENCODED_STRING_REF_EMPTY,
        inline_string: ptr::null(),
    }
}

#[inline]
fn trim_to_last_char_boundary(string: &str, max_len: usize) -> &[u8] {
    let mut len = string.len();
    if string.len() > max_len {
        // Trim to the last unicode character that fits within the max length.
        // We search for the last character boundary that is immediately followed
        // by another character boundary (end followed by beginning).
        len = max_len;
        while len > 0 {
            if string.is_char_boundary(len - 1) && string.is_char_boundary(len) {
                break;
            }
            len -= 1;
        }
    }
    &string.as_bytes()[0..len]
}

// translated from trace-engine/types.h for inlining
// The resulting `trace_string_ref_t` only lives as long as the input `string`.
#[inline]
fn trace_make_inline_string_ref(string: &str) -> sys::trace_string_ref_t {
    let len = string.len() as u32;
    if len == 0 {
        return trace_make_empty_string_ref();
    }

    let string =
        trim_to_last_char_boundary(string, sys::TRACE_ENCODED_STRING_REF_MAX_LENGTH as usize);

    sys::trace_string_ref_t {
        encoded_value: sys::TRACE_ENCODED_STRING_REF_INLINE_FLAG | len,
        inline_string: string.as_ptr() as *const libc::c_char,
    }
}

/// RAII wrapper for a trace context for a specific category.
pub struct TraceCategoryContext {
    raw: *const sys::trace_context_t,
    category_ref: sys::trace_string_ref_t,
}

impl TraceCategoryContext {
    #[inline]
    pub fn acquire(category: &'static CStr) -> Option<TraceCategoryContext> {
        unsafe {
            let mut category_ref = mem::MaybeUninit::<sys::trace_string_ref_t>::uninit();
            let raw = sys::trace_acquire_context_for_category(
                category.as_ptr(),
                category_ref.as_mut_ptr(),
            );
            if raw != ptr::null() {
                Some(TraceCategoryContext { raw, category_ref: category_ref.assume_init() })
            } else {
                None
            }
        }
    }

    #[inline]
    pub fn register_string_literal(&self, name: &'static CStr) -> sys::trace_string_ref_t {
        unsafe {
            let mut name_ref = mem::MaybeUninit::<sys::trace_string_ref_t>::uninit();
            sys::trace_context_register_string_literal(
                self.raw,
                name.as_ptr(),
                name_ref.as_mut_ptr(),
            );
            name_ref.assume_init()
        }
    }

    #[inline]
    fn register_current_thread(&self) -> sys::trace_thread_ref_t {
        unsafe {
            let mut thread_ref = mem::MaybeUninit::<sys::trace_thread_ref_t>::uninit();
            sys::trace_context_register_current_thread(self.raw, thread_ref.as_mut_ptr());
            thread_ref.assume_init()
        }
    }

    #[inline]
    pub fn write_instant(&self, name_ref: sys::trace_string_ref_t, scope: Scope, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_instant_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                scope.into_raw(),
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    pub fn write_instant_with_inline_name(&self, name: &str, scope: Scope, args: &[Arg<'_>]) {
        let name_ref = trace_make_inline_string_ref(name);
        self.write_instant(name_ref, scope, args)
    }

    fn write_counter(&self, name_ref: sys::trace_string_ref_t, counter_id: u64, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_counter_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                counter_id,
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    pub fn write_counter_with_inline_name(&self, name: &str, counter_id: u64, args: &[Arg<'_>]) {
        let name_ref = trace_make_inline_string_ref(name);
        self.write_counter(name_ref, counter_id, args);
    }

    fn write_duration(
        &self,
        name_ref: sys::trace_string_ref_t,
        start_time: sys::trace_ticks_t,
        args: &[Arg<'_>],
    ) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_duration_event_record(
                self.raw,
                start_time,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    pub fn write_duration_with_inline_name(
        &self,
        name: &str,
        start_time: sys::trace_ticks_t,
        args: &[Arg<'_>],
    ) {
        let name_ref = trace_make_inline_string_ref(name);
        self.write_duration(name_ref, start_time, args);
    }

    fn write_duration_begin(&self, name_ref: sys::trace_string_ref_t, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_duration_begin_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    pub fn write_duration_begin_with_inline_name(&self, name: &str, args: &[Arg<'_>]) {
        let name_ref = trace_make_inline_string_ref(name);
        self.write_duration_begin(name_ref, args);
    }

    fn write_duration_end(&self, name_ref: sys::trace_string_ref_t, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_duration_end_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    pub fn write_duration_end_with_inline_name(&self, name: &str, args: &[Arg<'_>]) {
        let name_ref = trace_make_inline_string_ref(name);
        self.write_duration_end(name_ref, args);
    }

    fn write_async_begin(&self, id: Id, name_ref: sys::trace_string_ref_t, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_async_begin_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                id.into(),
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    pub fn write_async_begin_with_inline_name(&self, id: Id, name: &str, args: &[Arg<'_>]) {
        let name_ref = trace_make_inline_string_ref(name);
        self.write_async_begin(id, name_ref, args);
    }

    fn write_async_end(&self, id: Id, name_ref: sys::trace_string_ref_t, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_async_end_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                id.into(),
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    pub fn write_async_end_with_inline_name(&self, id: Id, name: &str, args: &[Arg<'_>]) {
        let name_ref = trace_make_inline_string_ref(name);
        self.write_async_end(id, name_ref, args);
    }

    fn write_async_instant(&self, id: Id, name_ref: sys::trace_string_ref_t, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_async_instant_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                id.into(),
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    fn write_blob(&self, name_ref: sys::trace_string_ref_t, bytes: &[u8], args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_blob_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                bytes.as_ptr() as *const core::ffi::c_void,
                bytes.len(),
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    fn write_flow_begin(&self, name_ref: sys::trace_string_ref_t, flow_id: Id, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_flow_begin_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                flow_id.into(),
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    fn write_flow_end(&self, name_ref: sys::trace_string_ref_t, flow_id: Id, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_flow_end_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                flow_id.into(),
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }

    fn write_flow_step(&self, name_ref: sys::trace_string_ref_t, flow_id: Id, args: &[Arg<'_>]) {
        let ticks = zx::ticks_get();
        let thread_ref = self.register_current_thread();
        unsafe {
            sys::trace_context_write_flow_step_event_record(
                self.raw,
                ticks,
                &thread_ref,
                &self.category_ref,
                &name_ref,
                flow_id.into(),
                args.as_ptr() as *const sys::trace_arg_t,
                args.len(),
            );
        }
    }
}

impl std::ops::Drop for TraceCategoryContext {
    fn drop(&mut self) {
        unsafe {
            sys::trace_release_context(self.raw);
        }
    }
}

/// RAII wrapper for trace contexts without a specific associated category.
pub struct Context {
    context: *const sys::trace_context_t,
}

impl Context {
    #[inline]
    pub fn acquire() -> Option<Self> {
        let context = unsafe { sys::trace_acquire_context() };
        if context.is_null() {
            None
        } else {
            Some(Self { context })
        }
    }

    #[inline]
    pub fn register_string_literal(&self, s: &'static CStr) -> sys::trace_string_ref_t {
        unsafe {
            let mut s_ref = mem::MaybeUninit::<sys::trace_string_ref_t>::uninit();
            sys::trace_context_register_string_literal(
                self.context,
                s.as_ptr(),
                s_ref.as_mut_ptr(),
            );
            s_ref.assume_init()
        }
    }

    pub fn write_blob_record(
        &self,
        type_: sys::trace_blob_type_t,
        name_ref: &sys::trace_string_ref_t,
        data: &[u8],
    ) {
        unsafe {
            sys::trace_context_write_blob_record(
                self.context,
                type_,
                name_ref as *const sys::trace_string_ref_t,
                data.as_ptr() as *const libc::c_void,
                data.len(),
            );
        }
    }
}

impl std::ops::Drop for Context {
    fn drop(&mut self) {
        unsafe { sys::trace_release_context(self.context) }
    }
}

pub struct ProlongedContext {
    context: *const sys::trace_prolonged_context_t,
}

impl ProlongedContext {
    pub fn acquire() -> Option<Self> {
        let context = unsafe { sys::trace_acquire_prolonged_context() };
        if context.is_null() {
            None
        } else {
            Some(Self { context })
        }
    }
}

impl Drop for ProlongedContext {
    fn drop(&mut self) {
        unsafe { sys::trace_release_prolonged_context(self.context) }
    }
}

unsafe impl Send for ProlongedContext {}

mod sys {
    #![allow(non_camel_case_types, unused)]
    use fuchsia_zircon::sys::{zx_handle_t, zx_koid_t, zx_obj_type_t, zx_status_t, zx_ticks_t};

    pub type trace_ticks_t = zx_ticks_t;
    pub type trace_counter_id_t = u64;
    pub type trace_async_id_t = u64;
    pub type trace_flow_id_t = u64;
    pub type trace_thread_state_t = u32;
    pub type trace_cpu_number_t = u32;
    pub type trace_string_index_t = u32;
    pub type trace_thread_index_t = u32;
    pub type trace_context_t = libc::c_void;
    pub type trace_prolonged_context_t = libc::c_void;

    pub type trace_encoded_string_ref_t = u32;
    pub const TRACE_ENCODED_STRING_REF_EMPTY: trace_encoded_string_ref_t = 0;
    pub const TRACE_ENCODED_STRING_REF_INLINE_FLAG: trace_encoded_string_ref_t = 0x8000;
    pub const TRACE_ENCODED_STRING_REF_LENGTH_MASK: trace_encoded_string_ref_t = 0x7fff;
    pub const TRACE_ENCODED_STRING_REF_MAX_LENGTH: trace_encoded_string_ref_t = 32000;
    pub const TRACE_ENCODED_STRING_REF_MIN_INDEX: trace_encoded_string_ref_t = 0x1;
    pub const TRACE_ENCODED_STRING_REF_MAX_INDEX: trace_encoded_string_ref_t = 0x7fff;

    pub type trace_encoded_thread_ref_t = u32;
    pub const TRACE_ENCODED_THREAD_REF_INLINE: trace_encoded_thread_ref_t = 0;
    pub const TRACE_ENCODED_THREAD_MIN_INDEX: trace_encoded_thread_ref_t = 0x01;
    pub const TRACE_ENCODED_THREAD_MAX_INDEX: trace_encoded_thread_ref_t = 0xff;

    pub type trace_state_t = libc::c_int;
    pub const TRACE_STOPPED: trace_state_t = 0;
    pub const TRACE_STARTED: trace_state_t = 1;
    pub const TRACE_STOPPING: trace_state_t = 2;

    pub type trace_scope_t = libc::c_int;
    pub const TRACE_SCOPE_THREAD: trace_scope_t = 0;
    pub const TRACE_SCOPE_PROCESS: trace_scope_t = 1;
    pub const TRACE_SCOPE_GLOBAL: trace_scope_t = 2;

    pub type trace_blob_type_t = libc::c_int;
    pub const TRACE_BLOB_TYPE_DATA: trace_blob_type_t = 1;
    pub const TRACE_BLOB_TYPE_LAST_BRANCH: trace_blob_type_t = 2;
    pub const TRACE_BLOB_TYPE_PERFETTO: trace_blob_type_t = 3;

    #[repr(C)]
    #[derive(Copy, Clone)]
    pub struct trace_string_ref_t {
        pub encoded_value: trace_encoded_string_ref_t,
        pub inline_string: *const libc::c_char,
    }

    // A trace_string_ref_t object is created from a string slice.
    // The trace_string_ref_t object is contained inside an Arg object.
    // whose lifetime matches the string slice to ensure that the memory
    // cannot be de-allocated during the trace.
    //
    // trace_string_ref_t is safe for Send + Sync because the memory that
    // inline_string points to is guaranteed to be valid throughout the trace.
    //
    // For more information, see the ArgValue implementation for &str in this file.
    unsafe impl Send for trace_string_ref_t {}
    unsafe impl Sync for trace_string_ref_t {}

    #[repr(C)]
    pub struct trace_thread_ref_t {
        pub encoded_value: trace_encoded_thread_ref_t,
        pub inline_process_koid: zx_koid_t,
        pub inline_thread_koid: zx_koid_t,
    }

    #[repr(C)]
    pub struct trace_arg_t {
        pub name_ref: trace_string_ref_t,
        pub value: trace_arg_value_t,
    }

    #[repr(C)]
    pub union trace_arg_union_t {
        pub int32_value: i32,
        pub uint32_value: u32,
        pub int64_value: i64,
        pub uint64_value: u64,
        pub double_value: libc::c_double,
        pub string_value_ref: trace_string_ref_t,
        pub pointer_value: libc::uintptr_t,
        pub koid_value: zx_koid_t,
        pub bool_value: bool,
        pub reserved_for_future_expansion: [libc::uintptr_t; 2],
    }

    pub type trace_arg_type_t = libc::c_int;
    pub const TRACE_ARG_NULL: trace_arg_type_t = 0;
    pub const TRACE_ARG_INT32: trace_arg_type_t = 1;
    pub const TRACE_ARG_UINT32: trace_arg_type_t = 2;
    pub const TRACE_ARG_INT64: trace_arg_type_t = 3;
    pub const TRACE_ARG_UINT64: trace_arg_type_t = 4;
    pub const TRACE_ARG_DOUBLE: trace_arg_type_t = 5;
    pub const TRACE_ARG_STRING: trace_arg_type_t = 6;
    pub const TRACE_ARG_POINTER: trace_arg_type_t = 7;
    pub const TRACE_ARG_KOID: trace_arg_type_t = 8;
    pub const TRACE_ARG_BOOL: trace_arg_type_t = 9;

    #[repr(C)]
    pub struct trace_arg_value_t {
        pub type_: trace_arg_type_t,
        pub value: trace_arg_union_t,
    }

    #[repr(C)]
    pub struct trace_handler_ops_t {
        pub is_category_enabled:
            unsafe fn(handler: *const trace_handler_t, category: *const libc::c_char) -> bool,
        pub trace_started: unsafe fn(handler: *const trace_handler_t),
        pub trace_stopped: unsafe fn(
            handler: *const trace_handler_t,
            async_ptr: *const (), //async_t,
            disposition: zx_status_t,
            buffer_bytes_written: libc::size_t,
        ),
        pub buffer_overflow: unsafe fn(handler: *const trace_handler_t),
    }

    #[repr(C)]
    pub struct trace_handler_t {
        pub ops: *const trace_handler_ops_t,
    }

    #[link(name = "trace-engine")]
    extern "C" {
        // From trace-engine/context.h

        pub fn trace_context_is_category_enabled(
            context: *const trace_context_t,
            category_literal: *const libc::c_char,
        ) -> bool;

        pub fn trace_context_register_string_copy(
            context: *const trace_context_t,
            string: *const libc::c_char,
            length: libc::size_t,
            out_ref: *mut trace_string_ref_t,
        );

        pub fn trace_context_register_string_literal(
            context: *const trace_context_t,
            string_literal: *const libc::c_char,
            out_ref: *mut trace_string_ref_t,
        );

        pub fn trace_context_register_category_literal(
            context: *const trace_context_t,
            category_literal: *const libc::c_char,
            out_ref: *mut trace_string_ref_t,
        ) -> bool;

        pub fn trace_context_register_current_thread(
            context: *const trace_context_t,
            out_ref: *mut trace_thread_ref_t,
        );

        pub fn trace_context_register_thread(
            context: *const trace_context_t,
            process_koid: zx_koid_t,
            thread_koid: zx_koid_t,
            out_ref: *mut trace_thread_ref_t,
        );

        pub fn trace_context_write_kernel_object_record(
            context: *const trace_context_t,
            koid: zx_koid_t,
            type_: zx_obj_type_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_kernel_object_record_for_handle(
            context: *const trace_context_t,
            handle: zx_handle_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_process_info_record(
            context: *const trace_context_t,
            process_koid: zx_koid_t,
            process_name_ref: *const trace_string_ref_t,
        );

        pub fn trace_context_write_thread_info_record(
            context: *const trace_context_t,
            process_koid: zx_koid_t,
            thread_koid: zx_koid_t,
            thread_name_ref: *const trace_string_ref_t,
        );

        pub fn trace_context_write_context_switch_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            cpu_number: trace_cpu_number_t,
            outgoing_thread_state: trace_thread_state_t,
            outgoing_thread_ref: *const trace_thread_ref_t,
            incoming_thread_ref: *const trace_thread_ref_t,
        );

        pub fn trace_context_write_log_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            log_message: *const libc::c_char,
            log_message_length: libc::size_t,
        );

        pub fn trace_context_write_instant_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            scope: trace_scope_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_send_alert(context: *const trace_context_t, name: *const libc::c_char);

        pub fn trace_context_write_counter_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            counter_id: trace_counter_id_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_duration_event_record(
            context: *const trace_context_t,
            start_time: trace_ticks_t,
            end_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_blob_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            blob: *const libc::c_void,
            blob_size: libc::size_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_duration_begin_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_duration_end_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_async_begin_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            async_id: trace_async_id_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_async_instant_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            async_id: trace_async_id_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_async_end_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            async_id: trace_async_id_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_flow_begin_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            flow_id: trace_flow_id_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_flow_step_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            flow_id: trace_flow_id_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_flow_end_event_record(
            context: *const trace_context_t,
            event_time: trace_ticks_t,
            thread_ref: *const trace_thread_ref_t,
            category_ref: *const trace_string_ref_t,
            name_ref: *const trace_string_ref_t,
            flow_id: trace_flow_id_t,
            args: *const trace_arg_t,
            num_args: libc::size_t,
        );

        pub fn trace_context_write_initialization_record(
            context: *const trace_context_t,
            ticks_per_second: u64,
        );

        pub fn trace_context_write_string_record(
            context: *const trace_context_t,
            index: trace_string_index_t,
            string: *const libc::c_char,
            length: libc::size_t,
        );

        pub fn trace_context_write_thread_record(
            context: *const trace_context_t,
            index: trace_thread_index_t,
            procss_koid: zx_koid_t,
            thread_koid: zx_koid_t,
        );

        pub fn trace_context_write_blob_record(
            context: *const trace_context_t,
            type_: trace_blob_type_t,
            name_ref: *const trace_string_ref_t,
            data: *const libc::c_void,
            size: libc::size_t,
        );

        pub fn trace_context_alloc_record(
            context: *const trace_context_t,
            num_bytes: libc::size_t,
        ) -> *const libc::c_void;

        // From trace-engine/handler.h
        /*
        pub fn trace_start_engine(
            async_ptr: *const async_t,
            handler: *const trace_handler_t,
            buffer: *const (),
            buffer_num_bytes: libc::size_t) -> zx_status_t;
            */

        pub fn trace_stop_engine(disposition: zx_status_t) -> zx_status_t;

        // From trace-engine/instrumentation.h

        pub fn trace_generate_nonce() -> u64;

        pub fn trace_state() -> trace_state_t;

        pub fn trace_is_category_enabled(category_literal: *const libc::c_char) -> bool;

        pub fn trace_acquire_context() -> *const trace_context_t;

        pub fn trace_acquire_context_for_category(
            category_literal: *const libc::c_char,
            out_ref: *mut trace_string_ref_t,
        ) -> *const trace_context_t;

        pub fn trace_release_context(context: *const trace_context_t);

        pub fn trace_acquire_prolonged_context() -> *const trace_prolonged_context_t;

        pub fn trace_release_prolonged_context(context: *const trace_prolonged_context_t);

        pub fn trace_register_observer(event: zx_handle_t) -> zx_status_t;

        pub fn trace_unregister_observer(event: zx_handle_t) -> zx_status_t;

        pub fn trace_notify_observer_updated(event: zx_handle_t);
    }
}

/// Arguments for `TraceFuture` and `TraceFutureExt`. Use `trace_future_args!` to construct this
/// object.
pub struct TraceFutureArgs<'a> {
    pub category: &'static CStr,
    pub name: &'static CStr,

    /// `TraceFuture::new` and `trace_future_args!` both check if the trace category is enabled. The
    /// trace context is acquired in `trace_future_args!` and is passed to `TraceFuture::new` to
    /// avoid acquiring it twice.
    pub context: Option<TraceCategoryContext>,

    /// The trace arguments to appear in every duration event written by the `TraceFuture`. `args`
    /// should be empty if `context` is `None`.
    pub args: Vec<Arg<'a>>,

    /// The flow id to use in the flow events that connect the duration events together. A flow id
    /// will be constructed with `Id::new()` if not provided.
    pub flow_id: Option<Id>,

    /// Use `trace_future_args!` to construct this object.
    pub _use_trace_future_args: (),
}

#[doc(hidden)]
#[macro_export]
macro_rules! __impl_trace_future_args {
    ($category:expr, $name:expr, $flow_id:expr $(, $key:expr => $val:expr)*) => {{
        let context = $crate::TraceCategoryContext::acquire($category);
        let args = if context.is_some() {
            vec![$($crate::ArgValue::of($key, $val)),*]
        } else {
            vec![]
        };
        $crate::TraceFutureArgs {
            category: $category,
            name: $name,
            context: context,
            args: args,
            flow_id: $flow_id,
            _use_trace_future_args: (),
        }
    }};
}

/// Macro for constructing `TraceFutureArgs`. The trace arguments won't be constructed if the
/// category is not enabled. If the category becomes enabled while the `TraceFuture` is still alive
/// then the duration events will still be written but without the trace arguments.
///
/// Example:
///
/// ```
/// async move {
///     ....
/// }.trace(trace_future_args!(c"category", c"name", "x" => 5, "y" => 10)).await;
/// ```
#[macro_export]
macro_rules! trace_future_args {
    ($category:expr, $name:expr $(, $key:expr => $val:expr)*) => {
        $crate::__impl_trace_future_args!($category, $name, None $(,$key => $val)*)
    };
    ($category:expr, $name:expr, $flow_id:expr $(, $key:expr => $val:expr)*) => {
        $crate::__impl_trace_future_args!($category, $name, Some($flow_id) $(,$key => $val)*)
    };
}

/// Extension trait for tracing futures.
pub trait TraceFutureExt: Future + Sized {
    /// Wraps a `Future` in a `TraceFuture`.
    ///
    /// Example:
    ///
    /// ```rust
    /// future.trace(trace_future_args!(c"category", c"name")).await;
    /// ```
    ///
    /// Which is equivalent to:
    ///
    /// ```rust
    /// TraceFuture::new(trace_future_args!(c"category", c"name"), future).await;
    /// ```
    fn trace<'a>(self, args: TraceFutureArgs<'a>) -> TraceFuture<'a, Self> {
        TraceFuture::new(args, self)
    }
}

impl<T: Future + Sized> TraceFutureExt for T {}

/// Wraps a `Future` and writes duration events when the future is created, dropped, and every time
/// it's polled. The duration events are connected by flow events.
#[pin_project(PinnedDrop)]
pub struct TraceFuture<'a, Fut: Future> {
    category: &'static CStr,
    name: &'static CStr,
    args: Vec<Arg<'a>>,
    flow_id: Option<Id>,
    #[pin]
    future: Fut,
}

impl<'a, Fut: Future> TraceFuture<'a, Fut> {
    pub fn new(args: TraceFutureArgs<'a>, future: Fut) -> Self {
        debug_assert!(
            args.context.is_some() || args.args.is_empty(),
            "There should not be any trace arguments when the category is disabled"
        );
        let mut this = Self {
            category: args.category,
            name: args.name,
            args: args.args,
            flow_id: args.flow_id,
            future: future,
        };
        if let Some(context) = args.context {
            this.trace_create(context);
        }
        this
    }

    #[cold]
    fn trace_create(&mut self, context: TraceCategoryContext) {
        let name_ref = context.register_string_literal(self.name);
        let flow_id = self.flow_id.get_or_insert_with(Id::new);
        let duration_start = zx::ticks_get();
        context.write_flow_begin(name_ref, *flow_id, &[]);
        self.args.push(ArgValue::of("state", "created"));
        context.write_duration(name_ref, duration_start, &self.args);
        self.args.pop();
    }

    #[cold]
    fn trace_poll(
        self: Pin<&mut Self>,
        context: TraceCategoryContext,
        cx: &mut std::task::Context<'_>,
    ) -> Poll<Fut::Output> {
        let this = self.project();
        let name_ref = context.register_string_literal(this.name);
        let flow_id = this.flow_id.get_or_insert_with(Id::new);
        let duration_start = zx::ticks_get();
        context.write_flow_step(name_ref, *flow_id, &[]);
        let result = this.future.poll(cx);
        let result_str: &'static str = if result.is_pending() { "pending" } else { "ready" };
        this.args.push(ArgValue::of("state", result_str));
        context.write_duration(name_ref, duration_start, &this.args);
        this.args.pop();
        result
    }

    #[cold]
    fn trace_drop(self: Pin<&mut Self>, context: TraceCategoryContext) {
        let this = self.project();
        let name_ref = context.register_string_literal(this.name);
        let flow_id = this.flow_id.get_or_insert_with(Id::new);
        let duration_start = zx::ticks_get();
        context.write_flow_end(name_ref, *flow_id, &[]);
        this.args.push(ArgValue::of("state", "dropped"));
        context.write_duration(name_ref, duration_start, &this.args);
        this.args.pop();
    }
}

impl<Fut: Future> Future for TraceFuture<'_, Fut> {
    type Output = Fut::Output;
    fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Fut::Output> {
        if let Some(context) = TraceCategoryContext::acquire(self.as_ref().get_ref().category) {
            self.trace_poll(context, cx)
        } else {
            self.project().future.poll(cx)
        }
    }
}

#[pin_project::pinned_drop]
impl<Fut: Future> PinnedDrop for TraceFuture<'_, Fut> {
    fn drop(self: Pin<&mut Self>) {
        if let Some(context) = TraceCategoryContext::acquire(self.as_ref().get_ref().category) {
            self.trace_drop(context);
        }
    }
}

#[cfg(test)]
mod test {
    use super::{trim_to_last_char_boundary, Id};

    #[test]
    fn trim_to_last_char_boundary_trims_to_last_character_boundary() {
        assert_eq!(b"x", trim_to_last_char_boundary("x", 5));
        assert_eq!(b"x", trim_to_last_char_boundary("x", 1));
        assert_eq!(b"", trim_to_last_char_boundary("x", 0));
        assert_eq!(b"xxxxx", trim_to_last_char_boundary("xxxxx", 6));
        assert_eq!(b"xxxxx", trim_to_last_char_boundary("xxxxx", 5));
        assert_eq!(b"xxxx", trim_to_last_char_boundary("xxxxx", 4));

        assert_eq!("💩".as_bytes(), trim_to_last_char_boundary("💩", 5));
        assert_eq!("💩".as_bytes(), trim_to_last_char_boundary("💩", 4));
        assert_eq!(b"", trim_to_last_char_boundary("💩", 3));
    }

    // Here, we're looking to make sure that successive calls to the function generate distinct
    // values. How those values are distinct is not particularly meaningful; the current
    // implementation yields sequential values, but that's not a behavior to rely on.
    #[test]
    fn test_id_new() {
        assert_ne!(Id::new(), Id::new());
    }
}
