// 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.
xunion Rule {
    LiteralRule literal;
};

/// 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 interface is intended to be implemented by package resolver components,
/// and used by repository administration tools.
[Discoverable]
protocol Engine {
    /// Begins a rule edit transaction.
    StartEditTransaction(request<EditTransaction> transaction);

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

    /// Return 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` is a request for an iterator.
    ListStatic(request<RuleIterator> iterator);

    /// Rewrite 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 `ZX_ERR_INVALID_ARGS` If `url` is not a valid `fuchsia-pkg://`
    ///    URL. See [`fuchsia-pkg URL`].
    ///
    /// [`fuchsia-pkg URL`]:
    ///    https://fuchsia.googlesource.com/fuchsia/+/master/docs/the-book/package_url.md
    TestApply(string url) -> (string rewritten) error zx.status;
};

protocol EditTransaction {
    /// Return 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` is a request for an iterator.
    ListDynamic(request<RuleIterator> iterator);

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

    /// Add 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.
    ///
    /// * status `ZX_OK` if the rule was staged to be added.
    /// * status `ZX_ERR_INVALID_ARGS` If `url` is not a valid `fuchsia-pkg://`
    ///    URL. See [`fuchsia-pkg URL`].
    ///
    /// [`fuchsia-pkg URL`]:
    ///    https://fuchsia.googlesource.com/fuchsia/+/master/docs/the-book/package_url.md
    Add(Rule rule) -> (zx.status status);

    /// Commit this transaction, or detect another transaction that committed
    /// before this one.
    ///
    /// * status `ZX_OK` the staged edits were successfully committed.
    /// * status `ZX_ERR_UNAVAILABLE` another transaction committed before this one.
    /// * status `ZX_ERR_ACCESS_DENIED` editing dynamic rewrite rules is permanently disabled.
    Commit() -> (zx.status status);
};

/// The iterator over all the rewrite rules defined in a [`Engine`].
protocol RuleIterator {
    /// Advance the iterator and return 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);
};
