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

/// This manages package repositories.
///
/// This is intended to be implemented by package resolver components, and used by
/// repository administration tools.
[Discoverable]
protocol RepositoryManager {
    /// Adds a repository. This will overwrite the repository if it already exists.
    ///
    /// + request `repo` a repository to add to the resolver.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_ACCESS_DENIED` if editing repositories is permanently disabled.
    ///     * `ZX_ERR_ALREADY_EXISTS` if the repository already exists.
    ///     * `ZX_ERR_INVALID_ARGS` if the repository is malformed.
    Add(RepositoryConfig repo) -> () error zx.status;

    /// Removes a repository.
    ///
    /// Removing a repository will prevent future packages from being cached from this repository,
    /// but in-flight downloads may not be interrupted.
    ///
    /// + request `repo_url` the URL of the repository we want to remove.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_ACCESS_DENIED` if editing repositories is permanently disabled or the
    ///       `repo_url` matches a static repository.
    ///     * `ZX_ERR_INVALID_ARGS` if the `repo_url` is malformed.
    ///     * `ZX_ERR_NOT_FOUND` if the repository does not exist.
    Remove(string repo_url) -> () error zx.status;

    /// Adds a mirror to a repository. This will overwrite the mirror if it already exists.
    ///
    /// + request `repo_url` the URL of the repository to add the mirror to.
    /// + request `mirror` the mirror config used to add the mirror.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_ALREADY_EXISTS` if the mirror for this repository already exists.
    ///     * `ZX_ERR_INVALID_ARGS` if the `repo_url` or the `mirror` is malformed.
    ///     * `ZX_ERR_NOT_FOUND` if the repository does not exist.
    AddMirror(string repo_url, MirrorConfig mirror) -> () error zx.status;

    /// Removes a mirror from a repository.
    ///
    /// Removing a mirror will prevent future packages from being cached from that mirror, but
    /// in-flight downloads may not be interrupted.
    ///
    /// + request `repo_url` the URL of the mirror's repository.
    /// + request `mirror_url` the URL of the mirror we want to remove.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_INVALID_ARGS` if the `repo_url` or the `mirror_url` is malformed.
    ///     * `ZX_ERR_NOT_FOUND` if the repository or mirror does not exist.
    RemoveMirror(string repo_url, string mirror_url) -> () error zx.status;

    /// Returns an iterator over all repositories.
    ///
    /// + request `iterator` a request for an iterator.
    List(request<RepositoryIterator> iterator);
};

/// The configuration necessary to connect to a repository and its mirrors.
table RepositoryConfig {
    /// A fuchsia-pkg URL identifying the repository. Required.
    ///
    /// Example: fuchsia-pkg://example.com/
    1: string repo_url;

    /// A vector of public keys that have signed the initial trusted root
    /// metadata. Required.
    ///
    /// These keys must match one of the trusted keys known to the system.
    2: vector<RepositoryKeyConfig> root_keys;

    /// The repository mirrors that serve the package contents. Required.
    3: vector<MirrorConfig> mirrors;

    /// The package URL of the system update package. Optional.
    ///
    /// Only used for the fuchsia-pkg://fuchsia.com/ repo.
    4: string update_package_url;

    /// The initial trusted root metadata version. Optional, defaulting to 1.
    ///
    /// This value describes the initial root metadata version the resolver will
    /// fetch to initialize trust, once it's signatures has been verified by the
    /// `root_keys`. It will then walk the chain of N+1, N+2, and etc to the
    /// latest version before the resolver fetches any targets.
    ///
    /// It is recommended that this `root_version` number and `root_keys ` are
    /// kept reasonably in sync with the most recent published version of the
    /// root metadata, as that avoids the risk of an old and unused root key
    /// being used to compromise resolvers during the trust initialization.
    5: uint32 root_version;

    /// The number of `root_keys` that need to have signed the root metadata for it
    /// to be considered trusted. This value must be greater than or equal to 1.
    /// Optional, defaulting to 1.
    6: uint32 root_threshold;

    /// Whether the package resolver should check attached storage for blobs and
    /// repository metadata.
    7: bool use_local_mirror;
};

/// The keys used by the repository to authenticate its packages.
///
/// The only supported algorithm at the moment is ed25519.
flexible union RepositoryKeyConfig {
    /// The raw ed25519 public key as binary data.
    1: bytes ed25519_key;
};

/// The configuration necessary to connect to a mirror.
table MirrorConfig {
    /// The base URL of the TUF metadata on this mirror. Required.
    1: string mirror_url;

    /// Whether or not to automatically monitor the mirror for updates. Required.
    2: bool subscribe;

    3: reserved;

    /// The URL where blobs from this mirror should be fetched.  Optional.
    /// Defaults to `mirror_url + "/blobs"`.
    4: string blob_mirror_url;
};

/// The iterator over all the repositories defined in a `PackageResolver`.
protocol RepositoryIterator {
    /// Advances the iterator and returns the next batch of repositories.
    ///
    /// - response `repos` a vector of `RepositoryConfig` repositories.
    ///   Will return an empty vector when there are no more repositories.
    Next() -> (vector<RepositoryConfig> repos);
};
