// 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"
/// }
/// ```
type LiteralRule = struct {
    /// The exact hostname to match.
    host_match string;

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

    /// 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.
    path_prefix_match string;

    /// 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.
    path_prefix_replacement string;
};

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

/// 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(resource struct {
        transaction server_end:EditTransaction;
    });

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

    /// 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(resource struct {
        iterator server_end:RuleIterator;
    });

    /// 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(struct {
        url string;
    }) -> (struct {
        rewritten string;
    }) 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(resource struct {
        iterator server_end:RuleIterator;
    });

    /// 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(struct {
        rule Rule;
    }) -> (struct {}) 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() -> (struct {}) 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 and then close the channel when there are no more rules.
    Next() -> (struct {
        rules vector<Rule>;
    });
};
