// Copyright 2023 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.session;

using fuchsia.url;

/// A protocol used to control the session's lifecycle.
@available(added=13)
@discoverable
open protocol Lifecycle {
    /// Starts the session.
    ///
    /// Returns after the session component has been created and started.
    ///
    /// * error `LifecycleError.NOT_FOUND` if `session_url` has not been provided
    ///   and there is no configured default session URL.
    /// * error `LifecycleError.ALREADY_STARTED` if a session has already been started.
    /// * error `LifecycleError.RESOLVE_COMPONENT_FAILED` if `session_url` could not be
    ///   resolved to a component.
    /// * error `LifecycleError.DESTROY_COMPONENT_FAILED` if an existing session component
    ///   could not be destroyed. The existing session remains running at this point.
    /// * error `LifecycleError.CREATE_COMPONENT_FAILED` if the session component
    ///   could not be started. No session will be running at this point.
    flexible Start(table {
        /// The component URL of the session.
        ///
        /// Optional. If omitted, uses the default configured session URL, if available.
        1: session_url string:fuchsia.url.MAX_URL_LENGTH;
    }) -> () error LifecycleError;

    /// Stops the session.
    ///
    /// Returns after the session component has been destroyed.
    ///
    /// * error `LifecycleError.NOT_FOUND` if the session has not been started.
    /// * error `LifecycleError.DESTROY_COMPONENT_FAILED` if the session component
    ///   could not be destroyed. The previous session will continue to exist at
    ///   this point and the component may be running.
    flexible Stop() -> () error LifecycleError;

    /// Restarts the session.
    ///
    /// This stops the existing session and starts a new session with the same
    /// session URL as the previous one.
    ///
    /// Returns once the new session component has been created and started.
    ///
    /// * error `LifecycleError.NOT_FOUND` if there is no existing session.
    /// * error `LifecycleError.RESOLVE_COMPONENT_FAILED` if the session URL
    ///   could not be resolved to a component.
    /// * error `LifecycleError.DESTROY_COMPONENT_FAILED` if the session component
    ///   could not be destroyed. The previous session will continue to exist at
    ///   this point and the component may be running.
    /// * error `LifecycleError.CREATE_COMPONENT_FAILED` if the session component
    ///   could not be started. No session will be running at this point.
    flexible Restart() -> () error LifecycleError;
};

/// An error that occurs when updating the lifecycle a session.
@available(added=13)
type LifecycleError = flexible enum {
    /// The session has not been started or there is no default session URL configured.
    NOT_FOUND = 1;

    /// The session has already been started.
    ALREADY_STARTED = 2;

    /// The session component could not be resolved.
    RESOLVE_COMPONENT_FAILED = 3;

    /// The session component could not be created.
    CREATE_COMPONENT_FAILED = 4;

    /// The session component could not be destroyed.
    DESTROY_COMPONENT_FAILED = 5;
};
