/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "alloc-util.h"
#include "bus-internal.h"
#include "bus-match.h"
#include "bus-message.h"
#include "fd-util.h"
#include "fileio.h"
#include "hexdecoct.h"
#include "sort-util.h"
#include "string-util.h"
#include "strv.h"

/* Example:
 *
 *  A: type=signal,sender=foo,interface=bar
 *  B: type=signal,sender=quux,interface=fips
 *  C: type=signal,sender=quux,interface=waldo
 *  D: type=signal,member=test
 *  E: sender=miau
 *  F: type=signal
 *  G: type=signal
 *
 *  results in this tree:
 *
 *  BUS_MATCH_ROOT
 *  + BUS_MATCH_MESSAGE_TYPE
 *  | ` BUS_MATCH_VALUE: value == signal
 *  |   + DBUS_MATCH_SENDER
 *  |   | + BUS_MATCH_VALUE: value == foo
 *  |   | | ` DBUS_MATCH_INTERFACE
 *  |   | |   ` BUS_MATCH_VALUE: value == bar
 *  |   | |     ` BUS_MATCH_LEAF: A
 *  |   | ` BUS_MATCH_VALUE: value == quux
 *  |   |   ` DBUS_MATCH_INTERFACE
 *  |   |     | BUS_MATCH_VALUE: value == fips
 *  |   |     | ` BUS_MATCH_LEAF: B
 *  |   |     ` BUS_MATCH_VALUE: value == waldo
 *  |   |       ` BUS_MATCH_LEAF: C
 *  |   + DBUS_MATCH_MEMBER
 *  |   | ` BUS_MATCH_VALUE: value == test
 *  |   |   ` BUS_MATCH_LEAF: D
 *  |   + BUS_MATCH_LEAF: F
 *  |   ` BUS_MATCH_LEAF: G
 *  ` BUS_MATCH_SENDER
 *    ` BUS_MATCH_VALUE: value == miau
 *      ` BUS_MATCH_LEAF: E
 */

static bool BUS_MATCH_IS_COMPARE(enum bus_match_node_type t) {
        return t >= BUS_MATCH_SENDER && t <= BUS_MATCH_ARG_HAS_LAST;
}

static bool BUS_MATCH_CAN_HASH(enum bus_match_node_type t) {
        return (t >= BUS_MATCH_MESSAGE_TYPE && t <= BUS_MATCH_PATH) ||
                (t >= BUS_MATCH_ARG && t <= BUS_MATCH_ARG_LAST) ||
                (t >= BUS_MATCH_ARG_HAS && t <= BUS_MATCH_ARG_HAS_LAST);
}

static void bus_match_node_free(struct bus_match_node *node) {
        assert(node);
        assert(node->parent);
        assert(!node->child);
        assert(node->type != BUS_MATCH_ROOT);
        assert(node->type < _BUS_MATCH_NODE_TYPE_MAX);

        if (node->parent->child) {
                /* We are apparently linked into the parent's child
                 * list. Let's remove us from there. */
                if (node->prev) {
                        assert(node->prev->next == node);
                        node->prev->next = node->next;
                } else {
                        assert(node->parent->child == node);
                        node->parent->child = node->next;
                }

                if (node->next)
                        node->next->prev = node->prev;
        }

        if (node->type == BUS_MATCH_VALUE) {
                /* We might be in the parent's hash table, so clean
                 * this up */

                if (node->parent->type == BUS_MATCH_MESSAGE_TYPE)
                        hashmap_remove(node->parent->compare.children, UINT_TO_PTR(node->value.u8));
                else if (BUS_MATCH_CAN_HASH(node->parent->type) && node->value.str)
                        hashmap_remove(node->parent->compare.children, node->value.str);

                free(node->value.str);
        }

        if (BUS_MATCH_IS_COMPARE(node->type)) {
                assert(hashmap_isempty(node->compare.children));
                hashmap_free(node->compare.children);
        }

        free(node);
}

static bool bus_match_node_maybe_free(struct bus_match_node *node) {
        assert(node);

        if (node->type == BUS_MATCH_ROOT)
                return false;

        if (node->child)
                return false;

        if (BUS_MATCH_IS_COMPARE(node->type) && !hashmap_isempty(node->compare.children))
                return true;

        bus_match_node_free(node);
        return true;
}

static bool value_node_test(
                struct bus_match_node *node,
                enum bus_match_node_type parent_type,
                uint8_t value_u8,
                const char *value_str,
                char **value_strv,
                sd_bus_message *m) {

        assert(node);
        assert(node->type == BUS_MATCH_VALUE);

        /* Tests parameters against this value node, doing prefix
         * magic and stuff. */

        switch (parent_type) {

        case BUS_MATCH_MESSAGE_TYPE:
                return node->value.u8 == value_u8;

        case BUS_MATCH_SENDER:
                if (streq_ptr(node->value.str, value_str))
                        return true;

                if (m->creds.mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
                        /* on kdbus we have the well known names list
                         * in the credentials, let's make use of that
                         * for an accurate match */

                        STRV_FOREACH(i, m->creds.well_known_names)
                                if (streq_ptr(node->value.str, *i))
                                        return true;

                } else {

                        /* If we don't have kdbus, we don't know the
                         * well-known names of the senders. In that,
                         * let's just hope that dbus-daemon doesn't
                         * send us stuff we didn't want. */

                        if (node->value.str[0] != ':' && value_str && value_str[0] == ':')
                                return true;
                }

                return false;

        case BUS_MATCH_DESTINATION:
        case BUS_MATCH_INTERFACE:
        case BUS_MATCH_MEMBER:
        case BUS_MATCH_PATH:
        case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:

                if (value_str)
                        return streq_ptr(node->value.str, value_str);

                return false;

        case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST: {
                STRV_FOREACH(i, value_strv)
                        if (streq_ptr(node->value.str, *i))
                                return true;

                return false;
        }

        case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
                if (value_str)
                        return namespace_simple_pattern(node->value.str, value_str);

                return false;

        case BUS_MATCH_PATH_NAMESPACE:
                return path_simple_pattern(node->value.str, value_str);

        case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
                if (value_str)
                        return path_complex_pattern(node->value.str, value_str);

                return false;

        default:
                assert_not_reached();
        }
}

static bool value_node_same(
                struct bus_match_node *node,
                enum bus_match_node_type parent_type,
                uint8_t value_u8,
                const char *value_str) {

        /* Tests parameters against this value node, not doing prefix
         * magic and stuff, i.e. this one actually compares the match
         * itself. */

        assert(node);
        assert(node->type == BUS_MATCH_VALUE);

        switch (parent_type) {

        case BUS_MATCH_MESSAGE_TYPE:
                return node->value.u8 == value_u8;

        case BUS_MATCH_SENDER:
        case BUS_MATCH_DESTINATION:
        case BUS_MATCH_INTERFACE:
        case BUS_MATCH_MEMBER:
        case BUS_MATCH_PATH:
        case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:
        case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST:
        case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
        case BUS_MATCH_PATH_NAMESPACE:
        case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
                return streq(node->value.str, value_str);

        default:
                assert_not_reached();
        }
}

int bus_match_run(
                sd_bus *bus,
                struct bus_match_node *node,
                sd_bus_message *m) {

        _cleanup_strv_free_ char **test_strv = NULL;
        const char *test_str = NULL;
        uint8_t test_u8 = 0;
        int r;

        assert(m);

        if (!node)
                return 0;

        if (bus && bus->match_callbacks_modified)
                return 0;

        /* Not these special semantics: when traversing the tree we
         * usually let bus_match_run() when called for a node
         * recursively invoke bus_match_run(). There's are two
         * exceptions here though, which are BUS_NODE_ROOT (which
         * cannot have a sibling), and BUS_NODE_VALUE (whose siblings
         * are invoked anyway by its parent. */

        switch (node->type) {

        case BUS_MATCH_ROOT:

                /* Run all children. Since we cannot have any siblings
                 * we won't call any. The children of the root node
                 * are compares or leaves, they will automatically
                 * call their siblings. */
                return bus_match_run(bus, node->child, m);

        case BUS_MATCH_VALUE:

                /* Run all children. We don't execute any siblings, we
                 * assume our caller does that. The children of value
                 * nodes are compares or leaves, they will
                 * automatically call their siblings */

                assert(node->child);
                return bus_match_run(bus, node->child, m);

        case BUS_MATCH_LEAF:

                if (bus) {
                        /* Don't run this match as long as the AddMatch() call is not complete yet.
                         *
                         * Don't run this match unless the 'after' counter has been reached.
                         *
                         * Don't run this match more than once per iteration */

                        if (node->leaf.callback->install_slot ||
                            m->read_counter <= node->leaf.callback->after ||
                            node->leaf.callback->last_iteration == bus->iteration_counter)
                                return bus_match_run(bus, node->next, m);

                        node->leaf.callback->last_iteration = bus->iteration_counter;
                }

                r = sd_bus_message_rewind(m, true);
                if (r < 0)
                        return r;

                /* Run the callback. And then invoke siblings. */
                if (node->leaf.callback->callback) {
                        _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
                        sd_bus_slot *slot;

                        slot = container_of(node->leaf.callback, sd_bus_slot, match_callback);
                        if (bus) {
                                bus->current_slot = sd_bus_slot_ref(slot);
                                bus->current_handler = node->leaf.callback->callback;
                                bus->current_userdata = slot->userdata;
                        }
                        r = node->leaf.callback->callback(m, slot->userdata, &error_buffer);
                        if (bus) {
                                bus->current_userdata = NULL;
                                bus->current_handler = NULL;
                                bus->current_slot = sd_bus_slot_unref(slot);
                        }

                        r = bus_maybe_reply_error(m, r, &error_buffer);
                        if (r != 0)
                                return r;

                        if (bus && bus->match_callbacks_modified)
                                return 0;
                }

                return bus_match_run(bus, node->next, m);

        case BUS_MATCH_MESSAGE_TYPE:
                test_u8 = m->header->type;
                break;

        case BUS_MATCH_SENDER:
                test_str = m->sender;
                /* FIXME: resolve test_str from a well-known to a unique name first */
                break;

        case BUS_MATCH_DESTINATION:
                test_str = m->destination;
                break;

        case BUS_MATCH_INTERFACE:
                test_str = m->interface;
                break;

        case BUS_MATCH_MEMBER:
                test_str = m->member;
                break;

        case BUS_MATCH_PATH:
        case BUS_MATCH_PATH_NAMESPACE:
                test_str = m->path;
                break;

        case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:
                (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG, &test_str);
                break;

        case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
                (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_PATH, &test_str);
                break;

        case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
                (void) bus_message_get_arg(m, node->type - BUS_MATCH_ARG_NAMESPACE, &test_str);
                break;

        case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST:
                (void) bus_message_get_arg_strv(m, node->type - BUS_MATCH_ARG_HAS, &test_strv);
                break;

        default:
                assert_not_reached();
        }

        if (BUS_MATCH_CAN_HASH(node->type)) {
                struct bus_match_node *found;

                /* Lookup via hash table, nice! So let's jump directly. */

                if (test_str)
                        found = hashmap_get(node->compare.children, test_str);
                else if (test_strv) {
                        STRV_FOREACH(i, test_strv) {
                                found = hashmap_get(node->compare.children, *i);
                                if (found) {
                                        r = bus_match_run(bus, found, m);
                                        if (r != 0)
                                                return r;
                                }
                        }

                        found = NULL;
                } else if (node->type == BUS_MATCH_MESSAGE_TYPE)
                        found = hashmap_get(node->compare.children, UINT_TO_PTR(test_u8));
                else
                        found = NULL;

                if (found) {
                        r = bus_match_run(bus, found, m);
                        if (r != 0)
                                return r;
                }
        } else
                /* No hash table, so let's iterate manually... */
                for (struct bus_match_node *c = node->child; c; c = c->next) {
                        if (!value_node_test(c, node->type, test_u8, test_str, test_strv, m))
                                continue;

                        r = bus_match_run(bus, c, m);
                        if (r != 0)
                                return r;

                        if (bus && bus->match_callbacks_modified)
                                return 0;
                }

        if (bus && bus->match_callbacks_modified)
                return 0;

        /* And now, let's invoke our siblings */
        return bus_match_run(bus, node->next, m);
}

static int bus_match_add_compare_value(
                struct bus_match_node *where,
                enum bus_match_node_type t,
                uint8_t value_u8,
                const char *value_str,
                struct bus_match_node **ret) {

        struct bus_match_node *c, *n = NULL;
        int r;

        assert(where);
        assert(IN_SET(where->type, BUS_MATCH_ROOT, BUS_MATCH_VALUE));
        assert(BUS_MATCH_IS_COMPARE(t));
        assert(ret);

        for (c = where->child; c && c->type != t; c = c->next)
                ;

        if (c) {
                /* Comparison node already exists? Then let's see if the value node exists too. */

                if (t == BUS_MATCH_MESSAGE_TYPE)
                        n = hashmap_get(c->compare.children, UINT_TO_PTR(value_u8));
                else if (BUS_MATCH_CAN_HASH(t))
                        n = hashmap_get(c->compare.children, value_str);
                else
                        for (n = c->child; n && !value_node_same(n, t, value_u8, value_str); n = n->next)
                                ;

                if (n) {
                        *ret = n;
                        return 0;
                }
        } else {
                /* Comparison node, doesn't exist yet? Then let's create it. */

                c = new0(struct bus_match_node, 1);
                if (!c) {
                        r = -ENOMEM;
                        goto fail;
                }

                c->type = t;
                c->parent = where;
                c->next = where->child;
                if (c->next)
                        c->next->prev = c;
                where->child = c;

                if (t == BUS_MATCH_MESSAGE_TYPE) {
                        c->compare.children = hashmap_new(NULL);
                        if (!c->compare.children) {
                                r = -ENOMEM;
                                goto fail;
                        }
                } else if (BUS_MATCH_CAN_HASH(t)) {
                        c->compare.children = hashmap_new(&string_hash_ops);
                        if (!c->compare.children) {
                                r = -ENOMEM;
                                goto fail;
                        }
                }
        }

        n = new0(struct bus_match_node, 1);
        if (!n) {
                r = -ENOMEM;
                goto fail;
        }

        n->type = BUS_MATCH_VALUE;
        n->value.u8 = value_u8;
        if (value_str) {
                n->value.str = strdup(value_str);
                if (!n->value.str) {
                        r = -ENOMEM;
                        goto fail;
                }
        }

        n->parent = c;
        if (c->compare.children) {

                if (t == BUS_MATCH_MESSAGE_TYPE)
                        r = hashmap_put(c->compare.children, UINT_TO_PTR(value_u8), n);
                else
                        r = hashmap_put(c->compare.children, n->value.str, n);

                if (r < 0)
                        goto fail;
        } else {
                n->next = c->child;
                if (n->next)
                        n->next->prev = n;
                c->child = n;
        }

        *ret = n;
        return 1;

fail:
        if (c)
                bus_match_node_maybe_free(c);

        if (n) {
                free(n->value.str);
                free(n);
        }

        return r;
}

static int bus_match_add_leaf(
                struct bus_match_node *where,
                struct match_callback *callback) {

        struct bus_match_node *n;

        assert(where);
        assert(IN_SET(where->type, BUS_MATCH_ROOT, BUS_MATCH_VALUE));
        assert(callback);

        n = new0(struct bus_match_node, 1);
        if (!n)
                return -ENOMEM;

        n->type = BUS_MATCH_LEAF;
        n->parent = where;
        n->next = where->child;
        if (n->next)
                n->next->prev = n;

        n->leaf.callback = callback;
        callback->match_node = n;

        where->child = n;

        return 1;
}

enum bus_match_node_type bus_match_node_type_from_string(const char *k, size_t n) {
        assert(k);

        if (n == 4 && startswith(k, "type"))
                return BUS_MATCH_MESSAGE_TYPE;
        if (n == 6 && startswith(k, "sender"))
                return BUS_MATCH_SENDER;
        if (n == 11 && startswith(k, "destination"))
                return BUS_MATCH_DESTINATION;
        if (n == 9 && startswith(k, "interface"))
                return BUS_MATCH_INTERFACE;
        if (n == 6 && startswith(k, "member"))
                return BUS_MATCH_MEMBER;
        if (n == 4 && startswith(k, "path"))
                return BUS_MATCH_PATH;
        if (n == 14 && startswith(k, "path_namespace"))
                return BUS_MATCH_PATH_NAMESPACE;

        if (n == 4 && startswith(k, "arg")) {
                int j;

                j = undecchar(k[3]);
                if (j < 0)
                        return -EINVAL;

                return BUS_MATCH_ARG + j;
        }

        if (n == 5 && startswith(k, "arg")) {
                int a, b;
                enum bus_match_node_type t;

                a = undecchar(k[3]);
                b = undecchar(k[4]);
                if (a <= 0 || b < 0)
                        return -EINVAL;

                t = BUS_MATCH_ARG + a * 10 + b;
                if (t > BUS_MATCH_ARG_LAST)
                        return -EINVAL;

                return t;
        }

        if (n == 8 && startswith(k, "arg") && startswith(k + 4, "path")) {
                int j;

                j = undecchar(k[3]);
                if (j < 0)
                        return -EINVAL;

                return BUS_MATCH_ARG_PATH + j;
        }

        if (n == 9 && startswith(k, "arg") && startswith(k + 5, "path")) {
                enum bus_match_node_type t;
                int a, b;

                a = undecchar(k[3]);
                b = undecchar(k[4]);
                if (a <= 0 || b < 0)
                        return -EINVAL;

                t = BUS_MATCH_ARG_PATH + a * 10 + b;
                if (t > BUS_MATCH_ARG_PATH_LAST)
                        return -EINVAL;

                return t;
        }

        if (n == 13 && startswith(k, "arg") && startswith(k + 4, "namespace")) {
                int j;

                j = undecchar(k[3]);
                if (j < 0)
                        return -EINVAL;

                return BUS_MATCH_ARG_NAMESPACE + j;
        }

        if (n == 14 && startswith(k, "arg") && startswith(k + 5, "namespace")) {
                enum bus_match_node_type t;
                int a, b;

                a = undecchar(k[3]);
                b = undecchar(k[4]);
                if (a <= 0 || b < 0)
                        return -EINVAL;

                t = BUS_MATCH_ARG_NAMESPACE + a * 10 + b;
                if (t > BUS_MATCH_ARG_NAMESPACE_LAST)
                        return -EINVAL;

                return t;
        }

        if (n == 7 && startswith(k, "arg") && startswith(k + 4, "has")) {
                int j;

                j = undecchar(k[3]);
                if (j < 0)
                        return -EINVAL;

                return BUS_MATCH_ARG_HAS + j;
        }

        if (n == 8 && startswith(k, "arg") && startswith(k + 5, "has")) {
                enum bus_match_node_type t;
                int a, b;

                a = undecchar(k[3]);
                b = undecchar(k[4]);
                if (a <= 0 || b < 0)
                        return -EINVAL;

                t = BUS_MATCH_ARG_HAS + a * 10 + b;
                if (t > BUS_MATCH_ARG_HAS_LAST)
                        return -EINVAL;

                return t;
        }

        return -EINVAL;
}

static int match_component_compare(const struct bus_match_component *a, const struct bus_match_component *b) {
        return CMP(a->type, b->type);
}

void bus_match_parse_free(struct bus_match_component *components, unsigned n_components) {
        for (unsigned i = 0; i < n_components; i++)
                free(components[i].value_str);

        free(components);
}

int bus_match_parse(
                const char *match,
                struct bus_match_component **ret_components,
                unsigned *ret_n_components) {

        struct bus_match_component *components = NULL;
        unsigned n_components = 0;
        int r;

        assert(match);
        assert(ret_components);
        assert(ret_n_components);

        while (*match != '\0') {
                const char *eq, *q;
                enum bus_match_node_type t;
                unsigned j = 0;
                _cleanup_free_ char *value = NULL;
                bool escaped = false, quoted;
                uint8_t u;

                /* Avahi's match rules appear to include whitespace, skip over it */
                match += strspn(match, " ");

                eq = strchr(match, '=');
                if (!eq) {
                        r = -EINVAL;
                        goto fail;
                }

                t = bus_match_node_type_from_string(match, eq - match);
                if (t < 0) {
                        r = -EINVAL;
                        goto fail;
                }

                quoted = eq[1] == '\'';

                for (q = eq + 1 + quoted;; q++) {

                        if (*q == '\0') {

                                if (quoted) {
                                        r = -EINVAL;
                                        goto fail;
                                } else {
                                        if (value)
                                                value[j] = '\0';
                                        break;
                                }
                        }

                        if (!escaped) {
                                if (*q == '\\') {
                                        escaped = true;
                                        continue;
                                }

                                if (quoted) {
                                        if (*q == '\'') {
                                                if (value)
                                                        value[j] = '\0';
                                                break;
                                        }
                                } else {
                                        if (*q == ',') {
                                                if (value)
                                                        value[j] = '\0';
                                                break;
                                        }
                                }
                        }

                        if (!GREEDY_REALLOC(value, j + 2)) {
                                r = -ENOMEM;
                                goto fail;
                        }

                        value[j++] = *q;
                        escaped = false;
                }

                if (!value) {
                        value = strdup("");
                        if (!value) {
                                r = -ENOMEM;
                                goto fail;
                        }
                }

                if (t == BUS_MATCH_MESSAGE_TYPE) {
                        r = bus_message_type_from_string(value, &u);
                        if (r < 0)
                                goto fail;

                        value = mfree(value);
                } else
                        u = 0;

                if (!GREEDY_REALLOC(components, n_components + 1)) {
                        r = -ENOMEM;
                        goto fail;
                }

                components[n_components++] = (struct bus_match_component) {
                        .type = t,
                        .value_str = TAKE_PTR(value),
                        .value_u8 = u,
                };

                if (q[quoted] == 0)
                        break;

                if (q[quoted] != ',') {
                        r = -EINVAL;
                        goto fail;
                }

                match = q + 1 + quoted;
        }

        /* Order the whole thing, so that we always generate the same tree */
        typesafe_qsort(components, n_components, match_component_compare);

        /* Check for duplicates */
        for (unsigned i = 0; i+1 < n_components; i++)
                if (components[i].type == components[i+1].type) {
                        r = -EINVAL;
                        goto fail;
                }

        *ret_components = components;
        *ret_n_components = n_components;

        return 0;

fail:
        bus_match_parse_free(components, n_components);
        return r;
}

char *bus_match_to_string(struct bus_match_component *components, unsigned n_components) {
        _cleanup_free_ char *buffer = NULL;
        size_t size = 0;
        int r;

        if (n_components <= 0)
                return strdup("");

        assert(components);

        FILE *f = open_memstream_unlocked(&buffer, &size);
        if (!f)
                return NULL;

        for (unsigned i = 0; i < n_components; i++) {
                char buf[32];

                if (i != 0)
                        fputc(',', f);

                fputs(bus_match_node_type_to_string(components[i].type, buf, sizeof(buf)), f);
                fputc('=', f);
                fputc('\'', f);

                if (components[i].type == BUS_MATCH_MESSAGE_TYPE)
                        fputs(bus_message_type_to_string(components[i].value_u8), f);
                else
                        fputs(components[i].value_str, f);

                fputc('\'', f);
        }

        r = fflush_and_check(f);
        safe_fclose(f);
        if (r < 0)
                return NULL;
        return TAKE_PTR(buffer);
}

int bus_match_add(
                struct bus_match_node *root,
                struct bus_match_component *components,
                unsigned n_components,
                struct match_callback *callback) {

        int r;

        assert(root);
        assert(callback);

        for (unsigned i = 0; i < n_components; i++) {
                r = bus_match_add_compare_value(root,
                                                components[i].type,
                                                components[i].value_u8,
                                                components[i].value_str,
                                                &root);
                if (r < 0)
                        return r;
        }

        return bus_match_add_leaf(root, callback);
}

int bus_match_remove(
                struct bus_match_node *root,
                struct match_callback *callback) {

        struct bus_match_node *node, *pp;

        assert(root);
        assert(callback);

        node = callback->match_node;
        if (!node)
                return 0;

        assert(node->type == BUS_MATCH_LEAF);

        callback->match_node = NULL;

        /* Free the leaf */
        pp = node->parent;
        bus_match_node_free(node);

        /* Prune the tree above */
        while (pp) {
                node = pp;
                pp = node->parent;

                if (!bus_match_node_maybe_free(node))
                        break;
        }

        return 1;
}

void bus_match_free(struct bus_match_node *node) {
        struct bus_match_node *c;

        if (!node)
                return;

        if (BUS_MATCH_CAN_HASH(node->type)) {

                HASHMAP_FOREACH(c, node->compare.children)
                        bus_match_free(c);

                assert(hashmap_isempty(node->compare.children));
        }

        while ((c = node->child))
                bus_match_free(c);

        if (node->type != BUS_MATCH_ROOT)
                bus_match_node_free(node);
}

const char* bus_match_node_type_to_string(enum bus_match_node_type t, char buf[], size_t l) {
        switch (t) {

        case BUS_MATCH_ROOT:
                return "root";

        case BUS_MATCH_VALUE:
                return "value";

        case BUS_MATCH_LEAF:
                return "leaf";

        case BUS_MATCH_MESSAGE_TYPE:
                return "type";

        case BUS_MATCH_SENDER:
                return "sender";

        case BUS_MATCH_DESTINATION:
                return "destination";

        case BUS_MATCH_INTERFACE:
                return "interface";

        case BUS_MATCH_MEMBER:
                return "member";

        case BUS_MATCH_PATH:
                return "path";

        case BUS_MATCH_PATH_NAMESPACE:
                return "path_namespace";

        case BUS_MATCH_ARG ... BUS_MATCH_ARG_LAST:
                return snprintf_ok(buf, l, "arg%i", t - BUS_MATCH_ARG);

        case BUS_MATCH_ARG_PATH ... BUS_MATCH_ARG_PATH_LAST:
                return snprintf_ok(buf, l, "arg%ipath", t - BUS_MATCH_ARG_PATH);

        case BUS_MATCH_ARG_NAMESPACE ... BUS_MATCH_ARG_NAMESPACE_LAST:
                return snprintf_ok(buf, l, "arg%inamespace", t - BUS_MATCH_ARG_NAMESPACE);

        case BUS_MATCH_ARG_HAS ... BUS_MATCH_ARG_HAS_LAST:
                return snprintf_ok(buf, l, "arg%ihas", t - BUS_MATCH_ARG_HAS);

        default:
                return NULL;
        }
}

void bus_match_dump(FILE *out, struct bus_match_node *node, unsigned level) {
        char buf[32];

        if (!node)
                return;

        fprintf(out, "%*s[%s]", 2 * (int) level, "", bus_match_node_type_to_string(node->type, buf, sizeof(buf)));

        if (node->type == BUS_MATCH_VALUE) {
                if (node->parent->type == BUS_MATCH_MESSAGE_TYPE)
                        fprintf(out, " <%u>\n", node->value.u8);
                else
                        fprintf(out, " <%s>\n", node->value.str);
        } else if (node->type == BUS_MATCH_ROOT)
                fputs(" root\n", out);
        else if (node->type == BUS_MATCH_LEAF)
                fprintf(out, " %p/%p\n", node->leaf.callback->callback,
                        container_of(node->leaf.callback, sd_bus_slot, match_callback)->userdata);
        else
                putc('\n', out);

        if (BUS_MATCH_CAN_HASH(node->type)) {
                struct bus_match_node *c;
                HASHMAP_FOREACH(c, node->compare.children)
                        bus_match_dump(out, c, level + 1);
        }

        for (struct bus_match_node *c = node->child; c; c = c->next)
                bus_match_dump(out, c, level + 1);
}

enum bus_match_scope bus_match_get_scope(const struct bus_match_component *components, unsigned n_components) {
        bool found_driver = false;

        if (n_components <= 0)
                return BUS_MATCH_GENERIC;

        assert(components);

        /* Checks whether the specified match can only match the
         * pseudo-service for local messages, which we detect by
         * sender, interface or path. If a match is not restricted to
         * local messages, then we check if it only matches on the
         * driver. */

        for (unsigned i = 0; i < n_components; i++) {
                const struct bus_match_component *c = components + i;

                if (c->type == BUS_MATCH_SENDER) {
                        if (streq_ptr(c->value_str, "org.freedesktop.DBus.Local"))
                                return BUS_MATCH_LOCAL;

                        if (streq_ptr(c->value_str, "org.freedesktop.DBus"))
                                found_driver = true;
                }

                if (c->type == BUS_MATCH_INTERFACE && streq_ptr(c->value_str, "org.freedesktop.DBus.Local"))
                        return BUS_MATCH_LOCAL;

                if (c->type == BUS_MATCH_PATH && streq_ptr(c->value_str, "/org/freedesktop/DBus/Local"))
                        return BUS_MATCH_LOCAL;
        }

        return found_driver ? BUS_MATCH_DRIVER : BUS_MATCH_GENERIC;
}
