// 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(struct {
        repo RepositoryConfig;
    }) -> (struct {}) 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(struct {
        repo_url string;
    }) -> (struct {}) 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(struct {
        repo_url string;
        mirror MirrorConfig;
    }) -> (struct {}) 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(struct {
        repo_url string;
        mirror_url string;
    }) -> (struct {}) error zx.status;

    /// Returns an iterator over all repositories.
    ///
    /// + request `iterator` a request for an iterator.
    List(resource struct {
        iterator server_end:RepositoryIterator;
    });
};

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

    /// 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: root_keys vector<RepositoryKeyConfig>;

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

    4: reserved; // Formerly update_package_url string;

    /// The initial trusted root metadata version. Optional, if absent presumed
    /// to be 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: root_version uint32;

    /// 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, if absent presumed to be 1.
    6: root_threshold uint32;

    /// Whether the package resolver should check attached storage for blobs and
    /// repository metadata. Optional, if absent presumed to be false.
    7: use_local_mirror bool;

    /// Controls how repository metadata is persisted across reboots. Optional, if absent presumed
    /// to be EPHEMERAL.
    8: storage_type RepositoryStorageType;
};

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

/// Where the repository storage is written to.
type RepositoryStorageType = strict enum {
    /// 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.
type MirrorConfig = table {
    /// The base URL of the TUF metadata on this mirror. Required.
    1: mirror_url string;

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

    // TODO(fxbug.dev/75789): Turn comment below into doc-comment.
    //
    // Removed. Previously used for `RepositoryBlobKey blob_key`.
    3: reserved;

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

/// 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() -> (struct {
        repos vector<RepositoryConfig>;
    });
};
