// Copyright 2020 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.sys2;

using fuchsia.component;
using fuchsia.io;

/// The maximum length of a storage instance ID.
/// A storage instance ID is a 256-bit UUID, which when encoded
/// in hex notation is 64 characters long.
const MAX_STORAGE_ID_LENGTH uint32 = 64;

type StatusError = strict enum {
    /// The storage provider returned an error to a request or the connection
    /// to the provider unexpectedly closed.
    PROVIDER = 1;

    /// Information returned by the storage provider appears to be invalid.
    RESPONSE_INVALID = 2;

    /// A call to the storage provider succeeded, but it returned unexpectedly
    /// empty data.
    STATUS_UNKNOWN = 3;

    /// This call is not supported.
    UNSUPPORTED = 4;
};

type DeletionError = strict enum {
    /// There was an error sending a request to the storage provider.
    CONNECTION = 1;

    /// The storage provider returned an error in response to a protocol
    /// request.
    PROTOCOL = 2;

    /// There was no storage available for deletion.
    NONE_AVAILABLE = 3;

    /// This call is not supported.
    UNSUPPORTED = 4;
};

@discoverable
closed protocol StorageAdmin {
    /// Opens the isolated directory for the given component. The open request will provision
    /// the storage if it hasn't been already.
    strict OpenComponentStorage(resource struct {
        relative_moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
        flags fuchsia.io.OpenFlags;
        mode fuchsia.io.ModeType;
        object server_end:fuchsia.io.Node;
    });

    /// Lists the descendant components under the specified realm that use the storage
    /// capability.
    /// Returns INSTANCE_NOT_FOUND if the realm does not exist, and INVALID_ARGS if
    /// |relative_moniker| is malformed.
    strict ListStorageInRealm(resource struct {
        relative_moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
        iterator server_end:StorageIterator;
    }) -> () error fuchsia.component.Error;

    /// Opens the isolated directory for the given storage ID. The open request will provision
    /// the storage if it hasn't been already.
    strict OpenComponentStorageById(resource struct {
        id string:MAX_STORAGE_ID_LENGTH;
        object server_end:fuchsia.io.Node;
    }) -> () error fuchsia.component.Error;

    /// Deletes the contents of the storage for this component. The moniker can be a regular
    /// moniker (ie, "foo/bar") or a moniker with internal instance IDs (unusual, ie, "foo:0/bar:0").
    /// Preserves the component's subdirectory itself within the storage backing directory.
    strict DeleteComponentStorage(struct {
        relative_moniker string:fuchsia.component.MAX_MONIKER_LENGTH;
    }) -> () error fuchsia.component.Error;

    /// Get the current status of the storage.
    strict GetStatus() -> (StorageStatus) error StatusError;

    /// Deletes the contents of all the storage. Storage directories are retained so any components
    /// using storage will be able to continue using it to create new files and directories.
    /// Returns fuchsia.component.Error::INTERNAL only if no storage at all could be cleared.
    /// Returns successfully even if some errors happen during the deletion progress.
    strict DeleteAllStorageContents() -> () error DeletionError;
};

/// An iterator protocol for returning a set of components using a storage capability. See
/// |StorageAdmin.ListStorageInRealm| for more information.
closed protocol StorageIterator {
    /// Retrieve the next set of components using the storage capability. The returned monikers
    /// are relative to the component that declares the storage capability. Returns an empty
    /// vector after all components have been returned.
    strict Next() -> (struct {
        relative_monikers vector<string:fuchsia.component.MAX_MONIKER_LENGTH>:MAX;
    });
};

/// Metadata about status of the storage
type StorageStatus = table {
    1: total_size uint64;
    2: used_size uint64;
};
