// 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.update.installer;

using fuchsia.pkg;

alias AttemptId = string:36; // 36 == strlen("01234567-89ab-cdef-0123-456789abcdef")

/// Updates the system.
///
/// This protocol is intended to be consumed by a component capable of
/// discovering when to update and what version of the system to install.
[Discoverable]
protocol Installer {
    /// Get the status of the last update attempt. If this device hasn't
    /// attempted an update since the last factory reset, every field in the
    /// result will be absent.
    ///
    /// - response `info` the status of the last update attempt, if available.
    GetLastUpdateResult() -> (UpdateResult info);

    /// Get the status of the given update attempt, if it exists. If this device
    /// hasn't attempted an update with the given `attempt_id` or forgotten about
    /// that attempt, every field in the result will be absent.
    ///
    /// + request `attempt_id` UUID identifying the requested update attempt.
    /// - response `info` the status of the last update attempt, if available.
    GetUpdateResult(AttemptId attempt_id) -> (UpdateResult info);

    /// Start an update if one is not running, or attach to a pending update
    /// attempt if one is running and
    /// [`Options.allow_attach_to_existing_attempt`] is true. If an update
    /// attempt is started or attached to, provide status updates through
    /// `monitor`.
    ///
    /// + request `url` The fuchsia-pkg URL of the update package to update to.
    /// + request `options` Configuration options for this update attempt.
    ///     Ignored or merged with the existing `options` if an update attempt
    ///     is already in progress.
    /// + request `monitor` A protocol on which to receive progress updates.
    /// + request `reboot_controller` An optional protocol to control the timing
    ///     of the reboot into the update system. If not provided, the update
    ///     attempt will initiate the reboot as soon as it is ready.
    ///
    /// - response `attempt_id` UUID identifying this update attempt. For
    ///     updates that require a reboot, components may use this identifier to
    ///     disambiguate the completion of this update attempt from new update
    ///     attempts that start post-reboot.
    StartUpdate(
        fuchsia.pkg.PackageUrl url,
        Options options,
        Monitor monitor,
        request<RebootController>? reboot_controller
        ) -> (AttemptId attempt_id) error UpdateNotStartedReason;

    /// Attempt to monitor a specific update attempt, if it exists. This request
    /// will not start an update if one is not already running.
    ///
    /// + request `attempt_id` UUID identifying the requested update attempt. If
    ///     not given, monitor any active update attempt.
    /// + request `monitor` A protocol on which to receive progress updates.
    ///
    /// - response `attached` Whether or not the provided monitor was attached
    ///     to an in-progress update attempt. If false, monitor will be closed
    ///     by the server.
    MonitorUpdate(
        AttemptId? attempt_id,
        Monitor monitor
        ) -> (bool attached);
};

/// Controls the timing of the reboot into the updated system.
///
/// If the client end of a [`RebootController`] is closed without calling
/// [`RebootController.Detach()`], the update attempt will fall back to the
/// default behavior of rebooting as soon as it is ready.
protocol RebootController {
    /// Informs the update attempt that it may reboot when ready, unblocking a
    /// pending reboot if it is already ready to reboot.
    ///
    /// If a controller is dropped without sending this request or
    /// [`RebootController.Detach`], the update attempt reclaims control of the
    /// timing of the reboot, behaving as if the update attempt was not given a
    /// [`RebootController`] at all.
    Unblock();

    /// Informs the update attempt that it should wait to reboot indefinitely,
    /// even if this [`RebootController`] connection is dropped.
    Detach();
};

/// Metadata about a prior update attempt.
table UpdateResult {
    /// Unique identifier for this specific update attempt. Always present.
    1: AttemptId attempt_id;

    /// fuchsia-pkg:// url for the update package associated with this update
    /// attempt. Always present.
    2: fuchsia.pkg.PackageUrl url;

    /// Configuration options for this update attempt. Always present.
    3: Options options;

    /// Terminal state of this update attempt. Always present if the update
    /// failed. None if the update succeeded.
    4: State state;
};

/// Configuration options for an update attempt.
table Options {
    /// What initiated this update attempt. Required.
    1: Initiator initiator;

    /// If an update is already in progress, it's acceptable to instead attach a
    /// Monitor to that in-progress update instead of failing this request to
    /// install the update.  Setting this option to true may convert situations
    /// that would have resulted in the ALREADY_IN_PROGRESS to be treated as
    /// non-error cases. A controller, if provided, will be ignored if the
    /// running update attempt already has a controller.
    2: bool allow_attach_to_existing_attempt;

    /// Determines if the installer should update the recovery partition if an
    /// update is available.  Defaults to true.
    3: bool should_write_recovery;
};

/// Who or what initiated the update installation.
enum Initiator {
    /// The install was initiated by an interactive user, or the user is
    /// otherwise blocked and waiting for the result of this update.
    USER = 0;

    /// The install was initiated by a service, in the background.
    SERVICE = 1;
};

/// The set of values that are returned by an request to start an update.
enum UpdateNotStartedReason {
    /// There was already another update attempt in progress when this request was
    /// made.  A new update attempt will not be started.
    ALREADY_IN_PROGRESS = 1;
};
