/***
    This file is part of PulseAudio.

    Copyright 2012 Lennart Poettering

    PulseAudio is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published
    by the Free Software Foundation; either version 2.1 of the License,
    or (at your option) any later version.

    PulseAudio is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
***/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>

#include <systemd/sd-login.h>

#include <pulse/xmalloc.h>

#include <pulsecore/module.h>
#include <pulsecore/log.h>
#include <pulsecore/hashmap.h>
#include <pulsecore/idxset.h>
#include <pulsecore/modargs.h>

PA_MODULE_AUTHOR("Lennart Poettering");
PA_MODULE_DESCRIPTION("Create a client for each login session of this user");
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_LOAD_ONCE(true);

static const char* const valid_modargs[] = {
    NULL
};

struct session {
    char *id;
    pa_client *client;
};

struct userdata {
    pa_module *module;
    pa_core *core;
    pa_hashmap *sessions, *previous_sessions;
    sd_login_monitor *monitor;
    pa_io_event *io;
};

static int add_session(struct userdata *u, const char *id) {
    struct session *session;
    pa_client_new_data data;

    session = pa_xnew(struct session, 1);
    session->id = pa_xstrdup(id);

    pa_client_new_data_init(&data);
    data.module = u->module;
    data.driver = __FILE__;
    pa_proplist_setf(data.proplist, PA_PROP_APPLICATION_NAME, "Login Session %s", id);
    pa_proplist_sets(data.proplist, "systemd-login.session", id);
    session->client = pa_client_new(u->core, &data);
    pa_client_new_data_done(&data);

    if (!session->client) {
        pa_xfree(session->id);
        pa_xfree(session);
        return -1;
    }

    pa_hashmap_put(u->sessions, session->id, session);

    pa_log_debug("Added new session %s", id);

    /* Positive exit_idle_time is only useful when we have no session tracking
     * capability, so we can set it to 0 now that we have detected a session.
     * The benefit of setting exit_idle_time to 0 is that pulseaudio will exit
     * immediately when the session ends. That in turn is useful, because some
     * systems (those that use pam_systemd but don't use systemd for managing
     * pulseaudio) clean $XDG_RUNTIME_DIR on logout, but fail to terminate all
     * services that depend on the files in $XDG_RUNTIME_DIR. The directory
     * contains our sockets, and if the sockets are removed without terminating
     * pulseaudio, a quick relogin will likely cause trouble, because a new
     * instance will be spawned while the old instance is still running. */
    if (u->core->exit_idle_time > 0)
        pa_core_set_exit_idle_time(u->core, 0);

    return 0;
}

static void free_session(struct session *session) {
    pa_assert(session);

    pa_log_debug("Removing session %s", session->id);

    pa_client_free(session->client);
    pa_xfree(session->id);
    pa_xfree(session);
}

static int get_session_list(struct userdata *u) {
    int r;
    char **sessions;
    pa_hashmap *h;
    struct session *o;

    pa_assert(u);

    r = sd_uid_get_sessions(getuid(), 0, &sessions);
    if (r < 0)
        return -1;

    /* We copy all sessions that still exist from one hashmap to the
     * other and then flush the remaining ones */

    h = u->previous_sessions;
    u->previous_sessions = u->sessions;
    u->sessions = h;

    if (sessions) {
        char **s;

        /* Note that the sessions array is allocated with libc's
         * malloc()/free() calls, hence do not use pa_xfree() to free
         * this here. */

        for (s = sessions; *s; s++) {
            o = pa_hashmap_remove(u->previous_sessions, *s);
            if (o)
                pa_hashmap_put(u->sessions, o->id, o);
            else
                add_session(u, *s);

            free(*s);
        }

        free(sessions);
    }

    pa_hashmap_remove_all(u->previous_sessions);

    return 0;
}

static void monitor_cb(
        pa_mainloop_api*a,
        pa_io_event* e,
        int fd,
        pa_io_event_flags_t events,
        void *userdata) {

    struct userdata *u = userdata;

    pa_assert(u);

    sd_login_monitor_flush(u->monitor);
    get_session_list(u);
}

int pa__init(pa_module *m) {
    struct userdata *u = NULL;
    pa_modargs *ma;
    sd_login_monitor *monitor = NULL;
    int r;

    pa_assert(m);

    /* If we are not actually running logind become a NOP */
    if (access("/run/systemd/seats/", F_OK) < 0)
        return 0;

    ma = pa_modargs_new(m->argument, valid_modargs);
    if (!ma) {
        pa_log("Failed to parse module arguments");
        goto fail;
    }

    r = sd_login_monitor_new("session", &monitor);
    if (r < 0) {
        pa_log("Failed to create session monitor: %s", strerror(-r));
        goto fail;
    }

    m->userdata = u = pa_xnew0(struct userdata, 1);
    u->core = m->core;
    u->module = m;
    u->sessions = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) free_session);
    u->previous_sessions = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) free_session);
    u->monitor = monitor;

    u->io = u->core->mainloop->io_new(u->core->mainloop, sd_login_monitor_get_fd(monitor), PA_IO_EVENT_INPUT, monitor_cb, u);

    if (get_session_list(u) < 0)
        goto fail;

    pa_modargs_free(ma);

    return 0;

fail:
    if (ma)
        pa_modargs_free(ma);

    pa__done(m);

    return -1;
}

void pa__done(pa_module *m) {
    struct userdata *u;

    pa_assert(m);

    u = m->userdata;
    if (!u)
        return;

    if (u->sessions) {
        pa_hashmap_free(u->sessions);
        pa_hashmap_free(u->previous_sessions);
    }

    if (u->io)
        m->core->mainloop->io_free(u->io);

    if (u->monitor)
        sd_login_monitor_unref(u->monitor);

    pa_xfree(u);
}
