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

library fuchsia.tracing.provider;

using zx;

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

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

/// The maximum length of a category name.
const uint32 MAX_CATEGORY_NAME_LENGTH = 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(ProviderConfig config);

    /// 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(StartOptions options);

    /// 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, ForDeprecatedCBindings]
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(Provider provider, zx.koid pid, string:MAX_PROVIDER_NAME_LENGTH name);

    /// 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(Provider provider, zx.koid pid, string:MAX_PROVIDER_NAME_LENGTH name) -> (zx.status s, bool started);
};

/// The trace buffering mode.
enum BufferingMode : 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.
resource struct ProviderConfig {
    /// `buffering_mode` specifies what happens when the buffer fills.
    BufferingMode buffering_mode;

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

    /// 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.
    zx.handle:FIFO fifo;

    /// What trace categories to collect data for.
    vector<string:MAX_CATEGORY_NAME_LENGTH>:MAX_NUM_CATEGORIES 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.
enum BufferDisposition : 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.
struct StartOptions {
    /// 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.
    BufferDisposition buffer_disposition;

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