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

#include <string.h>

#include "alloc-util.h"
#include "logind-device.h"
#include "logind-seat-dbus.h"

Device* device_new(Manager *m, const char *sysfs, bool master) {
        Device *d;

        assert(m);
        assert(sysfs);

        d = new0(Device, 1);
        if (!d)
                return NULL;

        d->sysfs = strdup(sysfs);
        if (!d->sysfs)
                return mfree(d);

        if (hashmap_put(m->devices, d->sysfs, d) < 0) {
                free(d->sysfs);
                return mfree(d);
        }

        d->manager = m;
        d->master = master;
        dual_timestamp_get(&d->timestamp);

        return d;
}

static void device_detach(Device *d) {
        Seat *s;
        SessionDevice *sd;

        assert(d);

        if (!d->seat)
                return;

        while ((sd = d->session_devices))
                session_device_free(sd);

        s = d->seat;
        LIST_REMOVE(devices, d->seat->devices, d);
        d->seat = NULL;

        if (!seat_has_master_device(s)) {
                seat_add_to_gc_queue(s);
                seat_send_changed(s, "CanGraphical", NULL);
        }
}

void device_free(Device *d) {
        assert(d);

        device_detach(d);

        hashmap_remove(d->manager->devices, d->sysfs);

        free(d->sysfs);
        free(d);
}

void device_attach(Device *d, Seat *s) {
        bool had_master;

        assert(d);
        assert(s);

        if (d->seat == s)
                return;

        if (d->seat)
                device_detach(d);

        d->seat = s;
        had_master = seat_has_master_device(s);

        /* We keep the device list sorted by the "master" flag. That is, master
         * devices are at the front, other devices at the tail. As there is no
         * way to easily add devices at the list-tail, we need to iterate the
         * list to find the first non-master device when adding non-master
         * devices. We assume there is only a few (normally 1) master devices
         * per seat, so we iterate only a few times. */

        if (d->master || !s->devices)
                LIST_PREPEND(devices, s->devices, d);
        else
                LIST_FOREACH(devices, i, s->devices) {
                        if (!i->devices_next || !i->master) {
                                LIST_INSERT_AFTER(devices, s->devices, i, d);
                                break;
                        }
                }

        if (!had_master && d->master && s->started) {
                seat_save(s);
                seat_send_changed(s, "CanGraphical", NULL);
        }
}
