// Copyright 2021 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.audio;

using fuchsia.media2;
using fuchsia.mediastreams;
using zx;

/// Represents an audio consumer.
protocol Consumer {
    compose fuchsia.media2.ActiveConsumer;
    compose fuchsia.media2.ActiveConsumerStream;

    /// Connects a stream sink for the consumer with the indicated properties.
    ///
    /// + request `buffer_collection_token` a participant token for the buffer collection to be
    ///   used for this connection.
    /// + request `format` the format to be used for the is connection.
    /// + request `compression` the compression applied to packets in the stream. If this parameter
    ///   is not supplied, the stream is uncompressed (LPCM). If this parameter is supplied, its
    ///   value must be amoung the compression types listed in the `supported_compression_types`
    ///   field of the current consumer status. If the specified compression type used for a
    ///   connection ceases to be supported, the connection is closed, and the
    ///   `OnInputStreamDisconnected` event is signaled.
    /// + request `timestamp_units` the units used for timestamps on packets in this stream. If
    ///   this parameter is not supplied, packets may not have `specified` timestamps.
    /// + request `stream_sink_server_end` the server end of the `StreamSink` channel for this
    ///   connection.
    /// * error reason for connection failiure.
    ///
    /// Multiple stream sinks may be used sequentially for a given consumer. If the input stream is
    /// already connected, the new connection is used when the old one is closed from the client
    /// end and all messages from the old connection have been drained.
    ///
    /// This method responds when the connection is ready or the connect attempt fails.
    // TODO(dalesat): Consider switching to resource table when that is supported.
    ConnectInputStream(resource struct {
        buffer_collection_token zx.handle:EVENTPAIR;
        format fuchsia.mediastreams.AudioFormat;
        compression box<fuchsia.mediastreams.Compression>;
        timestamp_units box<fuchsia.media2.PacketTimestampUnits>;
        stream_sink_server_end server_end:fuchsia.media2.StreamSink;
    }) -> (struct {}) error fuchsia.media2.ConnectionError;

    /// Indicates that the current input stream has been disconnected unexpectedly.
    -> OnInputStreamDisconnected();

    /// Indicates that the stream sink previously created is invalid,
    /// and the client should create another one if it wishes to
    /// continue sending packets.
    -> OnInputStreamSinkInvalid();

    /// Gets the current status of the consumer using the long get pattern.
    ///
    /// - response `status` the current consumer status.
    ///
    /// The consumer replies immediately to this method when it is first called. The consumer
    /// replies to subsequent calls when the status has changed since the last call.
    WatchStatus() -> (struct {
        status ConsumerStatus;
    });
};

const MAX_COMPRESSION_TYPES uint32 = 256;

/// Represents the status of the consumer.
type ConsumerStatus = table {
    /// If present, indicates an error condition currently in effect.
    /// Absent if no error.
    // TODO(dalesat): Will we use this, or should this be done with epitaphs?
    1: error ConsumerError;

    /// If present, indicates the current relationship between the
    /// presentation timeline and reference clock. Absent initially.
    2: presentation_timeline fuchsia.media2.PresentationTimeline;

    /// Indicates the minimum lead time supported by this `Consumer`,
    /// that is, the minimum interval ahead of a packet’s effective
    /// presentation time that the packet must be submitted to prevent
    /// underflow.
    3: min_lead_time zx.duration;

    /// Indicates the maximum lead time supported by this `Consumer`,
    /// that is, the maximum interval ahead of a packet’s effective
    /// presentation time that the packet may be submitted to prevent
    /// overflow.
    4: max_lead_time zx.duration;

    /// Indicates whether rates other than 1.0 are supported.
    5: rate_supported bool;

    /// The currently-supported compression types. If this value is absent, no compression types
    /// are currently supported.
    6: supported_compression_types
            vector<fuchsia.mediastreams.CompressionType>:MAX_COMPRESSION_TYPES;

    // Whether uncompressed (LPCM) streams are currently supported. If this value is absent,
    // uncompressed streams are not currently supported.
    7: uncompressed_supported bool;
};

/// Represents an `Consumer` error condition.
// TODO: Define
type ConsumerError = strict enum {
    INTERNAL = 1;
};
