// 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.
@available(added=HEAD)
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>;
    });
};
