// 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
closed protocol Engine {
    /// Begins a rule edit transaction.
    ///
    /// + request `transaction` a request for an [`EditTransaction`].
    strict StartEditTransaction(resource struct {
        transaction server_end:EditTransaction;
    });

    /// Returns an iterator over all rewrite rules.
    ///
    /// + request `iterator` a request for an iterator.
    strict 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.
    strict 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
    strict TestApply(struct {
        url string;
    }) -> (struct {
        rewritten string;
    }) error zx.Status;
};

/// A unit of editing for rewrite rules.
closed 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.
    strict ListDynamic(resource struct {
        iterator server_end:RuleIterator;
    });

    /// Removes all dynamically configured rewrite rules, leaving only any
    /// statically configured rules.
    strict 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
    strict Add(struct {
        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.
    strict Commit() -> () error zx.Status;
};

/// The iterator over all the rewrite rules defined in a [`Engine`].
closed 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.
    strict Next() -> (struct {
        rules vector<Rule>;
    });
};
