// Copyright 2016 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;

/// Sessionmgr passes a connection to this service to the SessionShell so it can
/// operate on stories for the user.
///
/// Closing a `StoryProvider` connection has no effect on the state of the
/// framework.
@discoverable
protocol StoryProvider {
    /// Returns a list of existing stories. If `watcher` is provided, the client will
    /// be notified of story changes (new stories, deleted stories, runtime
    /// state changes).
    @transitional("Use GetStories2 instead")
    GetStories(resource struct {
        watcher client_end:<StoryProviderWatcher, optional>;
    }) -> (struct {
        story_infos vector<StoryInfo>:MAX;
    });
    /// For transition purposes only.
    @transitional("Only use while GetStories is transitional")
    GetStories2(resource struct {
        watcher client_end:<StoryProviderWatcher, optional>;
    }) -> (resource struct {
        story_infos vector<StoryInfo2>:MAX;
    });

    /// Requests detailed information about the given story. If the story doesn't
    /// exist, returns null.
    @transitional("Use GetStoryInfo2 instead")
    GetStoryInfo(struct {
        story_id string:MAX;
    }) -> (struct {
        story_info box<StoryInfo>;
    });
    /// For transition purposes only.
    @transitional("Use only while GetStoryInfo is transitional")
    GetStoryInfo2(struct {
        story_id string:MAX;
    }) -> (resource struct {
        story_info StoryInfo2;
    });

    /// Obtains a controller for a previously created story identified by its story
    /// ID. Obtaining the controller doesn't run it yet. If the story doesn't
    /// exist, the interface request is closed.
    GetController(resource struct {
        story_id string:MAX;
        request server_end:StoryController;
    });

    /// Registers a watcher for changes in the story collection.
    /// DEPRECATED: In favor of GetStories().
    Watch(resource struct {
        watcher client_end:StoryProviderWatcher;
    });
};

/// Implemented by clients of StoryProvider.
protocol StoryProviderWatcher {
    /// Called in three different situations:
    ///
    ///  * Immediately when a new watcher is registered with one OnChange()
    ///    invocation with the current infor and state of each story known on the
    ///    current device.
    ///
    ///  * Every time a change to StoryInfo is applied to the record of the story.
    ///
    ///  * Every time the StoryState of the story changes.
    ///
    /// The ID of the story the notifications are about are part of StoryInfo.
    ///
    /// `story_state` is STOPPED if the story was just created or just became known
    /// on this device and was not yet started on the current device. It's RUNNING
    /// when the story is started on the current device.
    ///
    /// `story_visibility_state` is deprecated and will always have a value of DEFAULT.
    @transitional("Implement OnChange2 instead")
    OnChange(struct {
        story_info StoryInfo;
        story_state StoryState;
        story_visibility_state StoryVisibilityState;
    });
    /// For transition purposes only.
    @transitional("Implement only while OnChange is transitional")
    OnChange2(resource struct {
        story_info StoryInfo2;
        story_state StoryState;
        story_visibility_state StoryVisibilityState;
    });

    /// Called when a story record is permanently deleted. The deletion could
    /// have originated on this or on another device.
    ///
    /// If the story is running on this device at the time it is deleted,
    /// OnChange() will not be called first.
    OnDelete(struct {
        story_id string:MAX;
    });
};

// Deprecated.
type StoryVisibilityState = strict enum {
    DEFAULT = 1;
    IMMERSIVE = 2;
};
