// 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.
library fuchsia.element;

using fuchsia.mem;

/// Maximum length of `AnnotationKey.namespace`.
const MAX_ANNOTATION_KEY_NAMESPACE_SIZE uint32 = 128;
/// Maximum length of `AnnotationKey.value`.
const MAX_ANNOTATION_KEY_VALUE_SIZE uint32 = 128;
/// Maximum number of annotations for a single element or view.
const MAX_ANNOTATIONS_PER_ELEMENT uint32 = 1024;

/// The key of an [`fuchsia.element/Annotation`].
type AnnotationKey = struct {
    /// A namespace that disambiguates groups of keys across clients.
    ///
    /// This is intended to group related keys together under the same
    /// identifier, and avoid naming collisions. For example, a session may
    /// use a custom namespace to define annotations that are specific
    /// to its implementation.
    ///
    /// The namespace is required and must be non-empty.
    ///
    /// The namespace "global" is represents the global namespace, reserved for
    /// annotations common across many products and session components.
    ///
    /// To ensure compatibility, clients should use a unique namespace,
    /// like a UUID or the client's component URL, when introducing new keys.
    namespace string:MAX_ANNOTATION_KEY_NAMESPACE_SIZE;

    /// An identifier for this annotation, uniquely identifying the annotation
    /// within `namespace`.
    value string:MAX_ANNOTATION_KEY_VALUE_SIZE;
};

/// The value of an [`fuchsia.element/Annotation`].
///
/// The actual field used depends on the type of annotation.
type AnnotationValue = strict resource union {
    1: text string:MAX;
    2: buffer fuchsia.mem.Buffer;
};

/// An annotation defined dynamically by key/value pair.
///
/// The Session Framework does not constrain the contents of `key` and `value`
/// in any way. Cooperating components that exchange annotations must define
/// and validate annotation entries based on their own conventions.
type Annotation = resource struct {
    /// An identfier for this annotation.
    key AnnotationKey;

    /// The content of this annotation.
    value AnnotationValue;
};

/// A list of annotations on an element.
alias Annotations = vector<Annotation>:MAX_ANNOTATIONS_PER_ELEMENT;

/// A list of annotation keys.
alias AnnotationKeys = vector<AnnotationKey>:MAX_ANNOTATIONS_PER_ELEMENT;

/// An interface to create, read, update, and delete annotations,
/// typically on an element or its view.
protocol AnnotationController {
    /// Adds, updates, and removes annotations.
    ///
    /// The server is expected to adhere to the following conventions:
    ///
    /// * If a key in `annotations_to_set` is new, a new annotation is added
    /// * If a key in `annotations_to_set` already exists, the annotation value is updated
    /// * If a key in `annotations_to_delete` does not exist, it is ignored
    ///
    /// The same key cannot appear twice in a call to UpdateAnnotations().  In other words,
    /// to set two Annotations with matching keys is illegal, as is an attempt to set an
    /// Annotation and also delete it.
    ///
    /// If the operation results in an error, the annotations remain unchanged,
    /// and will not be partially updated.
    ///
    /// * error `UpdateAnnotationsError.INVALID_ARGS` if the same key exists in
    ///   both `annotations_to_set` and `annotations_to_delete`.
    /// * error `UpdateAnnotationsError.INVALID_ARGS` if a key in `annotations_to_set` or
    ///   `annotations_to_delete` has an empty namespace.
    /// * error `UpdateAnnotationsError.INVALID_ARGS` if an `AnnotationValue.buffer` in
    ///   `annotations_to_set` could not be read.
    /// * error `UpdateAnnotationsError.TOO_MANY_ANNOTATIONS` if the operation results
    ///   in more than `MAX_ANNOTATIONS_PER_ELEMENT` annotations existing.
    UpdateAnnotations(resource struct {
        annotations_to_set Annotations;
        annotations_to_delete AnnotationKeys;
    }) -> () error UpdateAnnotationsError;

    /// Returns the current `Annotations` for the element.
    ///
    /// * error `GetAnnotationsError` if the annotations could not be returned.
    GetAnnotations() -> (resource struct {
        annotations Annotations;
    }) error GetAnnotationsError;

    /// Returns the full set of `Annotations` when one or more of them have changed, or
    /// when this method is called by the client for the first time.
    ///
    /// This operation does not block other requests from the client, but only one
    /// `WatchAnnotations` request at a time can be made on a connection. If the
    /// client makes a second `WatchAnnotations` request before waiting for the
    /// previous request to complete, the connection will be closed.
    ///
    /// * error `WatchAnnotationsError` if the annotations could not be returned.
    @transitional
    WatchAnnotations() -> (resource struct {
        annotations Annotations;
    }) error WatchAnnotationsError;
};

/// An error returned from `AnnotationController/UpdateAnnotations`
type UpdateAnnotationsError = strict enum {
    /// The arguments passed to `UpdateAnnotations` are malformed.
    INVALID_ARGS = 1;

    /// The total number of annotations will exceed [`MAX_ANNOTATIONS_PER_ELEMENT`]
    /// as a result of updating the annotations.
    TOO_MANY_ANNOTATIONS = 2;
};

/// An error returned from `ElementController/GetAnnotations`.
type GetAnnotationsError = strict enum {
    /// The `AnnotationValue.buffer` of an annotation could not be read.
    BUFFER_READ_FAILED = 1;
};

/// An error returned from `AnnotationController/WatchAnnotations` and
/// `ElementController/WatchAnnotations`.
type WatchAnnotationsError = flexible enum {
    /// The `AnnotationValue.buffer` of an annotation could not be read.
    BUFFER_READ_FAILED = 1;
};
