// 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.pkg;

using fuchsia.io;
using zx;

/// This manages the system package cache.
///
/// This is intended to be implemented by the package manager component and used by
/// package resolver components.
[Discoverable]
protocol PackageCache {
    /// Gets the package directory if it is present on the local system. If it is not, the
    /// `missing_blobs` iterator will provide all the blobs in the package that are missing from
    /// the system, and the ability to write those blobs to blobfs. If all the missing blobs are
    /// downloaded and written to by the client, the `dir` directory will be resolved. This method
    /// will return successfully when the package has been fully resolved, or return an error if
    /// the client closes `needed_blobs` or `dir` handle before the package has been resolved.
    ///
    /// This method does not guarantee the missing blobs have been persisted. In order to guarantee
    /// missing blobs are persisted, clients should call ['Sync'].
    ///
    /// + request `meta_far_blob` the blob info for the package's meta.far.
    /// + request `selectors` the package selectors (TODO: link to docs).
    /// + request `needed_blobs` an iterator over all the blobs in the package that
    ///   are not present on the system.
    /// + request `dir` an optional request for a directory that will be resolved when the package
    ///   has been successfully cached.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_UNAVAILABLE` if the client closed `needed_blobs` or `dir` handles before
    ///       all the missing blobs were downloaded to the system.
    Get(
        BlobInfo meta_far_blob,
        vector<string> selectors,
        request<NeededBlobs> needed_blobs,
        request<fuchsia.io.Directory>? dir
        ) -> () error zx.status;

    /// Opens the package, or errors out if it is not present on the local system.
    ///
    /// + request `meta_far_blob_id` the blob id for the package's meta.far.
    /// + request `selectors` the package selectors (TODO: link to docs).
    /// + request `dir` a request for a directory that will be resolved when the package has been
    ///   successfully cached.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_NOT_FOUND` if the package does not exist.
    Open(
        BlobId meta_far_blob_id,
        vector<string> selectors,
        request<fuchsia.io.Directory> dir
        ) -> () error zx.status;

    /// Retrieves a chunk iterator to the base package index.
    ///
    /// + request `iterator` a request for the `PackageIndexIterator` that will return sets of
    ///   `PackageIndexEntry` objects until all packages in the base index have been iterated.
    BasePackageIndex(request<PackageIndexIterator> iterator);

    /// Synchronizes updates to the cached packages to the underlying persistent storage.
    ///
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_INTERNAL` if the sync fails.
    Sync() -> () error zx.status;
};

/// This is used to fetch blobs that are not present on the local system for a
/// given package. This is provided by a [`PackageCache`] to the [`PackageResolver`].
protocol NeededBlobs {
    /// Returns a vector of blobs that are not present on the system that must be downloaded and
    /// written to blobfs with the `Open` method before a package can be resolved. This method
    /// should continue to be called until it returns an empty vector. This signifies all the
    /// missing blobs have been successfully downloaded.
    ///
    /// - response `blobs` the vector of missing blobs.
    GetMissingBlobs() -> (vector<BlobInfo> blobs);

    /// Opens a blob for writing.
    ///
    /// + request `blob_id` the blob id describing this blob.
    /// + request `file` resolves to an opened writable file must be truncated to the correct size
    ///   by the caller.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_ACCESS_DENIED` if the package does not contain this blob.
    ///     * `ZX_ERR_IO` if there is some other unspecified error during I/O.
    ///     * `ZX_ERR_NO_SPACE` if there is no space available to store the package.
    Open(BlobId blob_id, request<fuchsia.io.File> file) -> () error zx.status;
};

/// A chunk iterator for the package index. This is required because it is possible for the
/// package index to be too large to send over in a single request (over 64KiB).
protocol PackageIndexIterator {
    /// Returns the next chunk of package index entries. When the iterator is exhausted,
    /// this returns an empty vector.
    ///
    /// - response `entries` the next chunk of entries in the package index.
    Next() -> (vector<PackageIndexEntry>:MAX entries);
};
