// Copyright 2019 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.rewrite;

using zx;

/// A literal match and replacement rule.
///
/// # Examples
///
/// Replaces example.com with test.example.com for all packages
/// ```
/// {
///     host_match: "example.com"
///     host_replacement: "test.example.com"
///     path_prefix_match: "/"
///     path_prefix_replacement: "/"
/// }
/// ```
///
/// Replaces example.com with test.example.com for
/// fuchsia-pkg://example.com/rolldice. A package called "rolldice" in another
/// repo would not be rewritten.
/// ```
/// {
///     host_match: "example.com"
///     host_replacement: "test.example.com"
///     path_prefix_match: "/rolldice"
///     path_prefix_replacement: "/rolldice"
/// }
/// ```
///
/// Redirects all packages under "fuchsia-pkg://example.com/examples/" to
/// "fuchsia-pkg://example.com/examples/beta/".
/// ```
/// {
///     host_match: "example.com"
///     host_replacement: "example.com"
///     path_prefix_match: "/examples/"
///     path_prefix_replacement: "/examples/beta/"
/// }
/// ```
struct LiteralRule {
    /// The exact hostname to match.
    string host_match;

    /// The new hostname to replace the matched `host_match` with.
    string host_replacement;

    /// The absolute path to a package or directory to match against.
    ///
    /// If `path_prefix_match` ends with '/', it will match any packages or
    /// subdirectories below the matched path.
    /// If `path_prefix_match` does not end with '/', it will be interpreted as
    /// as an exact match.
    ///
    /// # Examples
    ///
    /// "/example" only matches a package called "example" at the root of the
    /// repo. "/parent/examples" and "/examples" would not match.
    ///
    /// "/example/" would match any package under the "example" path at the root
    /// of the repo.  For example, "/example/", "/example/package" would both
    /// match.
    string path_prefix_match;

    /// The absolute path to a single package or a directory to replace the
    /// matched `path_prefix_match` with.
    ///
    /// `path_prefix_match` and `path_prefix_replacement` must both match
    /// directories or both match exact packages. Mixing the two forms is not
    /// allowed.
    string path_prefix_replacement;
};

/// A rewrite rule, represented as an xunion for future compatibility.
flexible union Rule {
    1: LiteralRule literal;
};

/// This manages fuchsia-pkg:// rewrite rules.
///
/// When a package resolver is asked to resolve a fuchsia-pkg URL, it must first
/// iterate through its sequence of rewrite rules (given by [`List`]). The
/// rewrite engine will rewrite the given URL with the first rule that:
/// * matches the given URL
/// * produces a valid URL when applied to the given URL
/// If no rules match, the URL is resolved as-is.
///
/// This is intended to be implemented by package resolver components,
/// and used by repository administration tools.
[Discoverable]
protocol Engine {
    /// Begins a rule edit transaction.
    ///
    /// + request `transaction` a request for an [`EditTransaction`].
    StartEditTransaction(request<EditTransaction> transaction);

    /// Returns an iterator over all rewrite rules.
    ///
    /// + request `iterator` a request for an iterator.
    List(request<RuleIterator> iterator);

    /// Returns an iterator over all static (immutable) rewrite rules. These
    /// rules are handled as lower priority than dynamic rules and cannot be
    /// modified (although they can be overridden) by [`EditTransaction`]s.
    ///
    /// + request `iterator` a request for an iterator.
    ListStatic(request<RuleIterator> iterator);

    /// Rewrites the given `url` with the current rewrite rule set, returning the
    /// `rewritten` url.  If no rules match or a rule matches but performs an
    /// identity transformation, this API returns `url` unchanged.
    ///
    /// This API is intended only for reflecting on rule side effects. Using
    /// this API to pre-apply the rules, then passing the result to
    /// [`fuchsia.pkg/PackageResolver.Resolve`] would apply the rules twice.
    ///
    /// + request `url` the url to rewrite.
    /// - response `rewritten` the rewritten url.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_INVALID_ARGS` if `url` is not a valid `fuchsia-pkg://`
    ///       URL. See [`fuchsia-pkg URL`].
    ///
    /// [`fuchsia-pkg URL`]:
    ///    https://fuchsia.dev/fuchsia-src/concepts/storage/package_url
    TestApply(string url) -> (string rewritten) error zx.status;
};

/// A unit of editing for rewrite rules.
protocol EditTransaction {
    /// Returns an iterator over all dynamic (editable) rewrite rules. The
    /// iterator will reflect any changes made to the rewrite rules so far in
    /// this transaction.
    ///
    /// + request `iterator` a request for an iterator.
    ListDynamic(request<RuleIterator> iterator);

    /// Removes all dynamically configured rewrite rules, leaving only any
    /// statically configured rules.
    ResetAll();

    /// Adds a rewrite rule with highest priority. If `rule` already exists, this
    /// API will prioritize it over other rules.
    ///
    /// + request `rule` the rewrite rule to persist.
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_INVALID_ARGS` if `url` is not a valid `fuchsia-pkg://`
    ///      URL. See [`fuchsia-pkg URL`].
    ///
    /// [`fuchsia-pkg URL`]:
    ///    https://fuchsia.dev/fuchsia-src/concepts/storage/package_url
    Add(Rule rule) -> () error zx.status;

    /// Commits this transaction, or detect another transaction that committed
    /// before this one.
    ///
    /// * error a zx_status value indicating failure. One of the following:
    ///     * `ZX_ERR_UNAVAILABLE` if another transaction committed before this one.
    ///     * `ZX_ERR_ACCESS_DENIED` if editing dynamic rewrite rules is permanently disabled.
    Commit() -> () error zx.status;
};

/// The iterator over all the rewrite rules defined in a [`Engine`].
protocol RuleIterator {
    /// Advances the iterator and returns the next batch of rules.
    ///
    /// - response `rules` a vector of [`Rule`] rules. Will return an empty
    ///    vector when there are no more rules.
    Next() -> (vector<Rule> rules);
};
