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

#include "bus-introspect.h"
#include "bus-object.h"
#include "macro.h"
#include "string-util.h"
#include "strv.h"

int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata) {
        int r;

        log_debug("Registering bus object implementation for path=%s iface=%s", impl->path, impl->interface);

        for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
                r = sd_bus_add_object_vtable(bus, NULL,
                                             impl->path,
                                             impl->interface,
                                             *p,
                                             userdata);
                if (r < 0)
                        return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
                                               impl->path,
                                               impl->interface);
        }

        for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
                r = sd_bus_add_fallback_vtable(bus, NULL,
                                               impl->path,
                                               impl->interface,
                                               p->vtable,
                                               p->object_find,
                                               userdata);
                if (r < 0)
                        return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
                                               impl->path,
                                               impl->interface);
        }

        if (impl->node_enumerator) {
                r = sd_bus_add_node_enumerator(bus, NULL,
                                               impl->path,
                                               impl->node_enumerator,
                                               userdata);
                if (r < 0)
                        return log_error_errno(r, "Failed to add node enumerator for %s: %m",
                                               impl->path);
        }

        if (impl->manager) {
                r = sd_bus_add_object_manager(bus, NULL, impl->path);
                if (r < 0)
                        return log_error_errno(r, "Failed to add object manager for %s: %m", impl->path);
        }

        for (size_t i = 0; impl->children && impl->children[i]; i++) {
                r = bus_add_implementation(bus, impl->children[i], userdata);
                if (r < 0)
                        return r;
        }

        return 0;
}

static const BusObjectImplementation* find_implementation(
                const char *pattern,
                const BusObjectImplementation* const* bus_objects) {

        for (size_t i = 0; bus_objects && bus_objects[i]; i++) {
                const BusObjectImplementation *impl = bus_objects[i];

                if (STR_IN_SET(pattern, impl->path, impl->interface))
                        return impl;

                impl = find_implementation(pattern, impl->children);
                if (impl)
                        return impl;
        }

        return NULL;
}

static int bus_introspect_implementation(
                struct introspect *intro,
                const BusObjectImplementation *impl) {
        int r;

        for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
                r = introspect_write_interface(intro, impl->interface, *p);
                if (r < 0)
                        return log_error_errno(r, "Failed to write introspection data: %m");
        }

        for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
                r = introspect_write_interface(intro, impl->interface, p->vtable);
                if (r < 0)
                        return log_error_errno(r, "Failed to write introspection data: %m");
        }

        return 0;
}

static void list_paths(
                FILE *out,
                const BusObjectImplementation* const* bus_objects) {

        for (size_t i = 0; bus_objects[i]; i++) {
                fprintf(out, "%s\t%s\n", bus_objects[i]->path, bus_objects[i]->interface);
                if (bus_objects[i]->children)
                        list_paths(out, bus_objects[i]->children);
        }
}

int bus_introspect_implementations(
                FILE *out,
                const char *pattern,
                const BusObjectImplementation* const* bus_objects) {

        const BusObjectImplementation *impl, *main_impl = NULL;
        _cleanup_free_ char *s = NULL;
        int r;

        if (streq(pattern, "list")) {
                list_paths(out, bus_objects);
                return 0;
        }

        struct introspect intro = {};
        bool is_interface = sd_bus_interface_name_is_valid(pattern);

        impl = find_implementation(pattern, bus_objects);
        if (!impl)
                return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
                                       "%s %s not found",
                                       is_interface ? "Interface" : "Object path",
                                       pattern);

        /* We use trusted=false here to get all the @org.freedesktop.systemd1.Privileged annotations. */
        r = introspect_begin(&intro, false);
        if (r < 0)
                return log_error_errno(r, "Failed to write introspection data: %m");

        r = introspect_write_default_interfaces(&intro, impl->manager);
        if (r < 0)
                return log_error_errno(r, "Failed to write introspection data: %m");

        /* Check if there is a non-fallback path that applies to the given interface, also
         * print it. This is useful in the case of units: o.fd.systemd1.Service is declared
         * as a fallback vtable for o/fd/systemd1/unit, and we also want to print
         * o.fd.systemd1.Unit, which is the non-fallback implementation. */
        if (impl->fallback_vtables && is_interface)
                main_impl = find_implementation(impl->path, bus_objects);

        if (main_impl)
                bus_introspect_implementation(&intro, main_impl);

        if (impl != main_impl)
                bus_introspect_implementation(&intro, impl);

        _cleanup_set_free_ Set *nodes = NULL;

        for (size_t i = 0; impl->children && impl->children[i]; i++) {
                r = set_put_strdup(&nodes, impl->children[i]->path);
                if (r < 0)
                        return log_oom();
        }

        r = introspect_write_child_nodes(&intro, nodes, impl->path);
        if (r < 0)
                return r;

        r = introspect_finish(&intro, &s);
        if (r < 0)
                return log_error_errno(r, "Failed to write introspection data: %m");

        fputs(s, out);
        return 0;
}
