// Copyright 2018 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.modular;

enum ExecuteStatus {
    OK = 0;

    // Encountered an invalid command.
    INVALID_COMMAND = 1;

    // The `story_id` provided does not exist or is not visible
    // to this client.
    INVALID_STORY_ID = 2;

    // A story must contain at least one mod, and the commands given
    // either don't add one, or remove the last one.
    STORY_MUST_HAVE_MODS = 3;

    // The mod name specified in AddMod, RemoveMod or SendModCommand
    // was not found, or is invalid.
    INVALID_MOD = 4;

    // Resolution of the intent provided in AddMod returned zero results.
    NO_MODULES_FOUND = 5;

    // Some error happened while executing the command.
    INTERNAL_ERROR = 6;
};

enum ConfigureStoryError : int32 {
    /// The story cannot be (re)configured because it was already created.
    ERR_STORY_ALREADY_CREATED = 1;
};

struct ExecuteResult {
    ExecuteStatus status;
    string:MAX? story_id;
    string:MAX? error_message;
};

// Enables control of a session. A session, conceptually, is a single
// full-screen experience of a Fuchsia device. A device can run multiple
// sessions (ie, when one device powers multiple kiosks); that said, sessions
// are siloed from each other.
//
// A session, concretely, is a collection of stories, their state, the modules
// within them, any agents that run to support the mods and the various UI
// shells (session and story shells).
[Discoverable]
protocol PuppetMaster {
    // Requests a capability to control a story by name. The name acts as the
    // story's unique ID.  Calling ControlStory() for the same story name will
    // control the same story.
    //
    // The story name, as well as modification to the story, are durable and
    // persist across device reboots. This allows the client to assign its own
    // identifiers to stories. Clients wishing to guarantee a new story is
    // created should generate a UUIDv4 or similar.
    //
    // `request` is closed if control cannot be granted.
    //
    // TODO(thatguy): We want story names to be scoped to the client's namespace.
    ControlStory(string:MAX story_name, request<StoryPuppetMaster> request);

    // Deletes a story associated to `story_name`.
    // Any active StoryPuppetMaster connections to the Story will be closed.
    DeleteStory(string:MAX story_name) -> ();

    // Returns a list of all the names of stories in the session.
    GetStories() -> (vector<string:MAX>:MAX story_names);
};

protocol StoryPuppetMaster {
    // Enqueues the given `commands` in the order they are given.
    // Can be called as many times as necessary to specify the full
    // set of changes to the story.
    //
    // To execute all enqueued commands, call Execute().
    Enqueue(vector<StoryCommand>:MAX commands);

    // Executes the commands enqueued so far by Enqueue() in order and as
    // a batch: no other commands from other clients will be interleaved.
    //
    // If an error occurs, execution is stopped and an error code
    // and message are returned in `result`.
    Execute() -> (ExecuteResult result);

    // Set the `StoryInfo` extra field for a story that is to be
    // created. This should be called before the first call to Execute().
    // Any subsequent calls (either on the same channel or on a new
    // StoryPuppetMaster for an existing story) are ignored.
    // See story_info.fidl for details.
    //
    // DEPRECATED. This method is a no-op and will never return an error.
    [Transitional = "Deprecated, no-op"]
    SetStoryInfoExtra(vector<StoryInfoExtraEntry>:MAX story_info_extra)
        -> () error ConfigureStoryError;

    /// Attach the `annotations` to the story. If the story does not yet exist,
    /// it will be created.
    ///
    /// Existing annotations with the same key will be overwritten, or
    /// deleted if new value is null.
    Annotate(vector<Annotation>:MAX_ANNOTATIONS_PER_UPDATE annotations)
        -> () error AnnotationError;

    /// Returns the annotations attached to this story.
    ///
    /// This is a "hanging get" that returns the current annotations on
    /// first call, and on subsequent calls returns the full set of
    /// annotations once they are updated.
    ///
    /// Returns AnnotationError.NOT_FOUND if the story does not exist.
    WatchAnnotations() -> (vector<Annotation>:MAX_ANNOTATIONS_PER_STORY annotations) error AnnotationError;
};
