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

/// Error codes for PackageResolver operations.
// TODO(fxb/46003): Use this instead of zx.status for `GetHash`
type ResolveError = strict enum : int32 {
    /// The resolver encountered an otherwise unspecified error while handling the request.
    INTERNAL = 1;

    /// The resolver does not have permission to fetch a package blob.
    ACCESS_DENIED = 2;

    /// Some unspecified error during I/O.
    IO = 3;

    /// The package blob does not exist.
    BLOB_NOT_FOUND = 4;

    /// The package does not exist.
    PACKAGE_NOT_FOUND = 5;

    /// The resolver does not know about the repo.
    REPO_NOT_FOUND = 6;

    /// There is no space available to store the package or metadata.
    NO_SPACE = 7;

    /// The resolver is currently unable to fetch a package blob.
    UNAVAILABLE_BLOB = 8;

    /// The resolver is currently unable to fetch a repository's metadata.
    UNAVAILABLE_REPO_METADATA = 9;

    /// The `package_url` provided to resolver is invalid.
    INVALID_URL = 10;

    /// The `context` provided to resolver is invalid.
    INVALID_CONTEXT = 11;
};

/// This resolves packages from a repository.
///
/// This is intended to be implemented by package resolver components, and used by
/// repository administration tools.
@discoverable
protocol PackageResolver {
    /// Populates or updates the cache of a package using an absolute package
    /// URL.
    ///
    /// Ensures that a package, and any transitive subpackages, are on the local
    /// filesystem.
    ///
    /// + request `package_url` the absolute package URL for a package.  The
    ///   following link describes the format:
    ///   https://fuchsia.dev/fuchsia-src/concepts/packages/package_url.
    ///   Resource paths are not allowed.
    /// + request `dir` a request for a directory that will be resolved when the
    ///   package has been successfully cached.
    /// + returns a `resolved_context`, which can be passed to
    ///   `ResolveWithContext`, with a relative URL, to resolve a subpackage of
    ///   this package.
    /// * error indicates failure. See `ResolveError` for values and error
    ///   scenarios.
    // TODO(fxbug.dev/45811) change `package_url` from string to PackageUrl
    Resolve(resource struct {
        package_url string;
        dir server_end:fuchsia.io.Directory;
    }) -> (struct {
        resolved_context ResolutionContext;
    }) error ResolveError;

    /// Populates or updates the cache of a package using either an absolute or
    /// a relative package URL. If relative, the package will be resolved
    /// relative to the supplied `context`.
    ///
    /// Ensures that a package is on the local filesystem.
    ///
    /// + request `package_url` the absolute or relative package URL for a
    ///   package. If absolute, the `context` is ignored, and the behavior is
    ///   identical to calling `Resolve()`. A relative `package_url` is a
    ///   subpackage name.
    /// + request `context` a `ResolutionContext` associated with a previously
    ///   resolved package, for resolving subpackages relative to that package.
    /// + request `dir` a request for a directory that will be resolved when the
    ///   package has been successfully cached.
    /// + returns a `resolved_context`, which can be passed to a subsequent call
    ///   to `ResolveWithContext`, with a relative URL, to resolve a subpackage
    ///   of this package or subpackage.
    /// * error indicates failure. See `ResolveError` for values and error
    ///   scenarios.
    // TODO(fxbug.dev/45811) change `package_url` from string to PackageUrl
    ResolveWithContext(resource struct {
        package_url string;
        context ResolutionContext;
        dir server_end:fuchsia.io.Directory;
    }) -> (struct {
        resolved_context ResolutionContext;
    }) error ResolveError;

    /// Determines the hash of a package.
    ///
    /// + request `package_url` the package URL for a package.
    /// - response `meta_far_blob_id` the hash of the package.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_INTERNAL` if the resolver encountered an otherwise unspecified error
    ///       while handling the request.
    ///     * `ZX_ERR_NOT_FOUND` if the package does not exist in the repository specified by
    ///       `package_url`.
    ///     * `ZX_ERR_BAD_STATE` if the resolver does not know about the repository specified by
    ///       `package_url`.
    GetHash(struct {
        package_url PackageUrl;
    }) -> (struct {
        meta_far_blob_id BlobId;
    }) error zx.status;
};
