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

#include "alloc-util.h"
#include "bus-polkit.h"
#include "missing_capability.h"
#include "resolved-dnssd-bus.h"
#include "resolved-dnssd.h"
#include "resolved-link.h"
#include "resolved-manager.h"
#include "strv.h"
#include "user-util.h"

int bus_dnssd_method_unregister(sd_bus_message *message, void *userdata, sd_bus_error *error) {
        DnssdService *s = userdata;
        DnssdTxtData *txt_data;
        Manager *m;
        Link *l;
        int r;

        assert(message);
        assert(s);

        m = s->manager;

        r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
                                    "org.freedesktop.resolve1.unregister-service",
                                    NULL, false, s->originator,
                                    &m->polkit_registry, error);
        if (r < 0)
                return r;
        if (r == 0)
                return 1; /* Polkit will call us back */

        HASHMAP_FOREACH(l, m->links) {
                if (l->mdns_ipv4_scope) {
                        r = dns_scope_announce(l->mdns_ipv4_scope, true);
                        if (r < 0)
                                log_warning_errno(r, "Failed to send goodbye messages in IPv4 scope: %m");

                        dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, s->ptr_rr);
                        dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, s->srv_rr);
                        LIST_FOREACH(items, txt_data, s->txt_data_items)
                                dns_zone_remove_rr(&l->mdns_ipv4_scope->zone, txt_data->rr);
                }

                if (l->mdns_ipv6_scope) {
                        r = dns_scope_announce(l->mdns_ipv6_scope, true);
                        if (r < 0)
                                log_warning_errno(r, "Failed to send goodbye messages in IPv6 scope: %m");

                        dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, s->ptr_rr);
                        dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, s->srv_rr);
                        LIST_FOREACH(items, txt_data, s->txt_data_items)
                                dns_zone_remove_rr(&l->mdns_ipv6_scope->zone, txt_data->rr);
                }
        }

        dnssd_service_free(s);

        manager_refresh_rrs(m);

        return sd_bus_reply_method_return(message, NULL);
}

static int dnssd_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
        _cleanup_free_ char *name = NULL;
        Manager *m = userdata;
        DnssdService *service;
        int r;

        assert(bus);
        assert(path);
        assert(interface);
        assert(found);
        assert(m);

        r = sd_bus_path_decode(path, "/org/freedesktop/resolve1/dnssd", &name);
        if (r <= 0)
                return 0;

        service = hashmap_get(m->dnssd_services, name);
        if (!service)
                return 0;

        *found = service;
        return 1;
}

static int dnssd_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
        _cleanup_strv_free_ char **l = NULL;
        Manager *m = userdata;
        DnssdService *service;
        unsigned c = 0;
        int r;

        assert(bus);
        assert(path);
        assert(m);
        assert(nodes);

        l = new0(char*, hashmap_size(m->dnssd_services) + 1);
        if (!l)
                return -ENOMEM;

        HASHMAP_FOREACH(service, m->dnssd_services) {
                char *p;

                r = sd_bus_path_encode("/org/freedesktop/resolve1/dnssd", service->name, &p);
                if (r < 0)
                        return r;

                l[c++] = p;
        }

        l[c] = NULL;
        *nodes = TAKE_PTR(l);

        return 1;
}

static const sd_bus_vtable dnssd_vtable[] = {
        SD_BUS_VTABLE_START(0),

        SD_BUS_METHOD("Unregister", NULL, NULL, bus_dnssd_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
        SD_BUS_SIGNAL("Conflicted", NULL, 0),

        SD_BUS_VTABLE_END
};

const BusObjectImplementation dnssd_object = {
        "/org/freedesktop/resolve1/dnssd",
        "org.freedesktop.resolve1.DnssdService",
        .fallback_vtables = BUS_FALLBACK_VTABLES({dnssd_vtable, dnssd_object_find}),
        .node_enumerator = dnssd_node_enumerator,
};
