// 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.
closed 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.
    strict 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.
    strict 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.
    strict 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;
};
