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

    /// Controls how repository metadata is persisted across reboots. Default
    /// value is EPHEMERAL.
    8: RepositoryStorageType storage_type;
};

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

/// Where the repository storage is written to.
enum RepositoryStorageType {
    /// Ephemeral, or in-memory storage. This repository metadata will be lost
    /// when the process or device is restarted. The default type.
    EPHEMERAL = 1;

    /// Persistent, where the repository metadata is written to mutable storage
    /// and is available after a reboot.
    PERSISTENT = 2;
};

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