// 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, Layout = "Simple"]
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.
struct ProviderConfig {
    /// `buffering_mode` specifies what happens when the buffer fills.
    BufferingMode buffering_mode;

    /// The buffer to write trace records into.
    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.
    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;
};
