// 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 uint32 MAX_ANNOTATION_KEY_NAMESPACE_SIZE = 128;
/// Maximum length of `AnnotationKey.value`.
const uint32 MAX_ANNOTATION_KEY_VALUE_SIZE = 128;
/// Maximum number of annotations for a single element or view.
const uint32 MAX_ANNOTATIONS_PER_ELEMENT = 1024;

/// The key of an [`fuchsia.element/Annotation`].
struct AnnotationKey {
    /// 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.
    string:MAX_ANNOTATION_KEY_NAMESPACE_SIZE namespace;

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

/// The value of an [`fuchsia.element/Annotation`].
///
/// The actual field used depends on the type of annotation.
resource union AnnotationValue {
    1: string:MAX text;
    2: fuchsia.mem.Buffer 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.
resource struct Annotation {
    /// An identfier for this annotation.
    AnnotationKey key;

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

/// 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
    ///
    /// Annotations with the same key cannot be set and deleted in the same operation.
    ///
    /// 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(Annotations annotations_to_set, AnnotationKeys annotations_to_delete)
        -> () error UpdateAnnotationsError;

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

/// An error returned from `AnnotationController/UpdateAnnotations`
enum UpdateAnnotationsError {
    /// 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`.
enum GetAnnotationsError {
    /// The `AnnotationValue.buffer` of an annotation could not be read.
    BUFFER_READ_FAILED = 1;
};
