// 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
closed 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.
    strict Add(struct {
        repo RepositoryConfig;
    }) -> () 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.
    strict Remove(struct {
        repo_url string;
    }) -> () 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.
    strict AddMirror(struct {
        repo_url string;
        mirror MirrorConfig;
    }) -> () 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.
    strict RemoveMirror(struct {
        repo_url string;
        mirror_url string;
    }) -> () error zx.Status;

    /// Returns an iterator over all repositories.
    ///
    /// + request `iterator` a request for an iterator.
    strict 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 vector<uint8>:MAX;
};

/// 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`.
closed 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.
    strict Next() -> (struct {
        repos vector<RepositoryConfig>;
    });
};
