// 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.
@available(added=7)
library fuchsia.tracing.provider;

using zx;

/// The maximum length of a provider's name.
const MAX_PROVIDER_NAME_LENGTH uint32 = 100;

/// The maximum number of categories supported.
const MAX_NUM_CATEGORIES uint32 = 100;

/// The maximum length of a category name.
const MAX_CATEGORY_NAME_LENGTH uint32 = 100;

/// The provider interface which applications must implement and register
/// with the `TraceRegistry` to participate in tracing.
///
/// See //zircon/system/ulib/trace-provider/ for a C++ implementation of
/// this interface which can easily be configured by an application.
protocol Provider {
    /// Initialize tracing and prepare for writing trace records for events in
    /// the specified `categories` into `buffer` using `fifo` for signaling.
    /// Tracing hasn't started yet, a `Start()` call is still required.
    ///
    ///
    /// At most one trace can be active at a time. Subsequent `Initialize()`
    /// requests received prior to a `Terminate()` call must be ignored.
    Initialize(resource struct {
        config ProviderConfig;
    });

    /// Begin tracing.
    ///
    /// If tracing has already started the provider must ignore the request.
    ///
    /// There is no result. The provider must send a `TRACE_PROVIDER_STARTED`
    /// packet on `fifo` to indicate success/failure of starting.
    Start(struct {
        options StartOptions;
    });

    /// Stop tracing.
    ///
    /// If tracing has already stopped the provider must ignore the request.
    ///
    /// Once the provider has finished writing any final events to the trace
    /// buffer, it must send a `TRACE_PROVIDER_STOPPED` packet on `fifo`.
    /// Note that multiple `Start,Stop` requests can be received between
    /// `Initialize,Terminate`.
    Stop();

    /// Terminate tracing.
    ///
    /// Tracing is stopped first if not already stopped.
    /// After tracing has fully terminated the provider must close both
    /// `buffer` and `fifo` to indicate to the trace manager that tracing is
    /// finished.
    Terminate();
};

/// The service which trace providers use to register themselves with
/// the tracing system.
/// Note that one property of this interface is that once registration is made
/// the provider can drop this connection.
@discoverable
@for_deprecated_c_bindings
protocol Registry {
    /// Registers the trace provider.
    /// Note: Registration is asynchronous, it's only at some point after this
    /// returns that the provider is actually registered.
    /// To unregister, simply close the Provider pipe.
    /// `pid` is the process id of the provider, `name` is the name of the
    /// provider. Both of these are used in logging and diagnostic messages.
    RegisterProvider(resource struct {
        provider client_end:Provider;
        pid zx.koid;
        name string:MAX_PROVIDER_NAME_LENGTH;
    });

    /// Registers the trace provider synchronously. The call doesn't return
    /// until the provider is registered.
    /// On return `s` is `ZX_OK` if registration was successful.
    /// `started` is true if tracing has already started, which is a hint to
    /// the provider to wait for the Start() message before continuing if it
    /// wishes to not drop trace records before Start() is received.
    /// To unregister, simply close the Provider pipe.
    /// `pid` is the process id of the provider, `name` is the name of the
    /// provider. Both of these are used in logging and diagnostic messages.
    RegisterProviderSynchronously(resource struct {
        provider client_end:Provider;
        pid zx.koid;
        name string:MAX_PROVIDER_NAME_LENGTH;
    }) -> (struct {
        s zx.status;
        started bool;
    });
};

/// The trace buffering mode.
type BufferingMode = strict enum : uint8 {
    /// In oneshot mode there is only one buffer that is not reused. When the
    /// buffer fills the provider just keeps dropping records, keeping a count,
    /// and then when tracing stops the header is updated to record final
    /// state.
    ONESHOT = 1;

    /// In circular mode, the buffer is continually written to until tracing
    /// stops. When the buffer fills older records are discarded as needed.
    CIRCULAR = 2;

    /// In streaming mode, the buffer is effectively split into two pieces.
    /// When one half of the buffer fills the provider notifies the trace
    /// manager via the provided fifo, and then starts filling the other half
    /// of the buffer. When the buffer is saved, the manager responds via the
    /// provided fifo. If trace manager hasn't saved the buffer in time, and
    /// the other buffer fills, then the provider is required to drop records
    /// until space becomes available.
    STREAMING = 3;
};

/// Trace provider configuration.
// The configuration of a provider is split out into a struct so that we can
// add configuration data without changing the method signature. Structs still
// introduce ABI compatibility issues, this will be switched to a table when
// tables are ready for use in zircon.
type ProviderConfig = resource struct {
    /// `buffering_mode` specifies what happens when the buffer fills.
    buffering_mode BufferingMode;

    /// The buffer to write trace records into.
    buffer zx.handle:VMO;

    /// When the trace provider observes `ZX_FIFO_PEER_CLOSED` on `fifo`, it
    /// must assume the trace manager has terminated abnormally (since `Stop`
    /// was not received as usual) and stop tracing automatically, discarding
    /// any in-flight trace data.
    fifo zx.handle:FIFO;

    /// What trace categories to collect data for.
    categories vector<string:MAX_CATEGORY_NAME_LENGTH>:MAX_NUM_CATEGORIES;
};

/// Choices for clearing/retaining trace buffer contents at Start.
/// A brief summary of buffer contents:
/// The trace buffer is divided into two main pieces: durable and non-durable.
/// The durable portion contains things like the string and thread data for
/// their respective references (trace_encoded_string_ref_t and
/// trace_encoded_thread_ref_t). The non-durable portion contains the rest of
/// the trace data like events); this is the portion that, for example, is
/// discarded in circular buffering mode when the (non-durable) buffer fills.
type BufferDisposition = strict enum : uint8 {
    /// Clear the entire buffer, including durable buffer contents.
    /// N.B. If this is done mid-session, then string and thread references
    /// from prior to this point will become invalid - the underlying data
    /// will be gone. To prevent this save buffer contents before clearing.
    ///
    /// This is typically used when buffer contents were saved after the
    /// preceding Stop.
    CLEAR_ENTIRE = 1;

    /// Clear the non-durable portion of the buffer, retaining the durable
    /// portion.
    ///
    /// This is typically used when buffer contents were not saved after the
    /// preceding Stop and the current contents are to be discarded.
    CLEAR_NONDURABLE = 2;

    /// Retain buffer contents. New trace data is added where the previous
    /// trace run left off.
    ///
    /// This is typically used when buffer contents were not saved after the
    /// preceding Stop and the current contents are to be retained.
    RETAIN = 3;
};

/// Additional options to control tracing at start.
type StartOptions = struct {
    /// Whether and how to clear the buffer when starting data collection.
    /// This allows, for example, multiple Start/Stop trace runs to be
    /// collected in the same buffer.
    buffer_disposition BufferDisposition;

    /// The trace categories to add to the initial set provided in
    /// `ProviderConfig`.
    additional_categories vector<string:MAX_CATEGORY_NAME_LENGTH>:MAX_NUM_CATEGORIES;
};
