/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/

/* 
 * To list the properties of a device, try something like:
 * udevadm info -a -n snd/hwC0D0 (for a sound card)
 * udevadm info --query=all -n input/event3 (for a keyboard, mouse, etc)
 * udevadm info --query=property -n input/event2
 */
#include "SDL_udev.h"

#ifdef SDL_USE_LIBUDEV

#include <linux/input.h>

#include "SDL_assert.h"
#include "SDL_evdev_capabilities.h"
#include "SDL_loadso.h"
#include "SDL_timer.h"
#include "SDL_hints.h"
#include "../unix/SDL_poll.h"

static const char *SDL_UDEV_LIBS[] = { "libudev.so.1", "libudev.so.0" };

#define _THIS SDL_UDEV_PrivateData *_this
static _THIS = NULL;

static SDL_bool SDL_UDEV_load_sym(const char *fn, void **addr);
static int SDL_UDEV_load_syms(void);
static SDL_bool SDL_UDEV_hotplug_update_available(void);
static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev);

static SDL_bool
SDL_UDEV_load_sym(const char *fn, void **addr)
{
    *addr = SDL_LoadFunction(_this->udev_handle, fn);
    if (*addr == NULL) {
        /* Don't call SDL_SetError(): SDL_LoadFunction already did. */
        return SDL_FALSE;
    }

    return SDL_TRUE;
}

static int
SDL_UDEV_load_syms(void)
{
    /* cast funcs to char* first, to please GCC's strict aliasing rules. */
    #define SDL_UDEV_SYM(x) \
        if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->syms.x)) return -1

    SDL_UDEV_SYM(udev_device_get_action);
    SDL_UDEV_SYM(udev_device_get_devnode);
    SDL_UDEV_SYM(udev_device_get_subsystem);
    SDL_UDEV_SYM(udev_device_get_parent_with_subsystem_devtype);
    SDL_UDEV_SYM(udev_device_get_property_value);
    SDL_UDEV_SYM(udev_device_get_sysattr_value);
    SDL_UDEV_SYM(udev_device_new_from_syspath);
    SDL_UDEV_SYM(udev_device_unref);
    SDL_UDEV_SYM(udev_enumerate_add_match_property);
    SDL_UDEV_SYM(udev_enumerate_add_match_subsystem);
    SDL_UDEV_SYM(udev_enumerate_get_list_entry);
    SDL_UDEV_SYM(udev_enumerate_new);
    SDL_UDEV_SYM(udev_enumerate_scan_devices);
    SDL_UDEV_SYM(udev_enumerate_unref);
    SDL_UDEV_SYM(udev_list_entry_get_name);
    SDL_UDEV_SYM(udev_list_entry_get_next);
    SDL_UDEV_SYM(udev_monitor_enable_receiving);
    SDL_UDEV_SYM(udev_monitor_filter_add_match_subsystem_devtype);
    SDL_UDEV_SYM(udev_monitor_get_fd);
    SDL_UDEV_SYM(udev_monitor_new_from_netlink);
    SDL_UDEV_SYM(udev_monitor_receive_device);
    SDL_UDEV_SYM(udev_monitor_unref);
    SDL_UDEV_SYM(udev_new);
    SDL_UDEV_SYM(udev_unref);
    SDL_UDEV_SYM(udev_device_new_from_devnum);
    SDL_UDEV_SYM(udev_device_get_devnum);
    #undef SDL_UDEV_SYM

    return 0;
}

static SDL_bool
SDL_UDEV_hotplug_update_available(void)
{
    if (_this->udev_mon != NULL) {
        const int fd = _this->syms.udev_monitor_get_fd(_this->udev_mon);
        if (SDL_IOReady(fd, SDL_FALSE, 0)) {
            return SDL_TRUE;
        }
    }
    return SDL_FALSE;
}


int
SDL_UDEV_Init(void)
{
    int retval = 0;
    
    if (_this == NULL) {
        _this = (SDL_UDEV_PrivateData *) SDL_calloc(1, sizeof(*_this));
        if(_this == NULL) {
            return SDL_OutOfMemory();
        }
        
        retval = SDL_UDEV_LoadLibrary();
        if (retval < 0) {
            SDL_UDEV_Quit();
            return retval;
        }
        
        /* Set up udev monitoring 
         * Listen for input devices (mouse, keyboard, joystick, etc) and sound devices
         */
        
        _this->udev = _this->syms.udev_new();
        if (_this->udev == NULL) {
            SDL_UDEV_Quit();
            return SDL_SetError("udev_new() failed");
        }

        _this->udev_mon = _this->syms.udev_monitor_new_from_netlink(_this->udev, "udev");
        if (_this->udev_mon == NULL) {
            SDL_UDEV_Quit();
            return SDL_SetError("udev_monitor_new_from_netlink() failed");
        }
        
        _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL);
        _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL);
        _this->syms.udev_monitor_enable_receiving(_this->udev_mon);
        
        /* Do an initial scan of existing devices */
        SDL_UDEV_Scan();

    }
    
    _this->ref_count += 1;
    
    return retval;
}

void
SDL_UDEV_Quit(void)
{
    SDL_UDEV_CallbackList *item;
    
    if (_this == NULL) {
        return;
    }
    
    _this->ref_count -= 1;
    
    if (_this->ref_count < 1) {
        
        if (_this->udev_mon != NULL) {
            _this->syms.udev_monitor_unref(_this->udev_mon);
            _this->udev_mon = NULL;
        }
        if (_this->udev != NULL) {
            _this->syms.udev_unref(_this->udev);
            _this->udev = NULL;
        }
        
        /* Remove existing devices */
        while (_this->first != NULL) {
            item = _this->first;
            _this->first = _this->first->next;
            SDL_free(item);
        }
        
        SDL_UDEV_UnloadLibrary();
        SDL_free(_this);
        _this = NULL;
    }
}

void
SDL_UDEV_Scan(void)
{
    struct udev_enumerate *enumerate = NULL;
    struct udev_list_entry *devs = NULL;
    struct udev_list_entry *item = NULL;  
    
    if (_this == NULL) {
        return;
    }
   
    enumerate = _this->syms.udev_enumerate_new(_this->udev);
    if (enumerate == NULL) {
        SDL_UDEV_Quit();
        SDL_SetError("udev_enumerate_new() failed");
        return;
    }
    
    _this->syms.udev_enumerate_add_match_subsystem(enumerate, "input");
    _this->syms.udev_enumerate_add_match_subsystem(enumerate, "sound");
    
    _this->syms.udev_enumerate_scan_devices(enumerate);
    devs = _this->syms.udev_enumerate_get_list_entry(enumerate);
    for (item = devs; item; item = _this->syms.udev_list_entry_get_next(item)) {
        const char *path = _this->syms.udev_list_entry_get_name(item);
        struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path);
        if (dev != NULL) {
            device_event(SDL_UDEV_DEVICEADDED, dev);
            _this->syms.udev_device_unref(dev);
        }
    }

    _this->syms.udev_enumerate_unref(enumerate);
}


void
SDL_UDEV_UnloadLibrary(void)
{
    if (_this == NULL) {
        return;
    }
    
    if (_this->udev_handle != NULL) {
        SDL_UnloadObject(_this->udev_handle);
        _this->udev_handle = NULL;
    }
}

int
SDL_UDEV_LoadLibrary(void)
{
    int retval = 0, i;
    
    if (_this == NULL) {
        return SDL_SetError("UDEV not initialized");
    }
 
    /* See if there is a udev library already loaded */
    if (SDL_UDEV_load_syms() == 0) {
        return 0;
    }

#ifdef SDL_UDEV_DYNAMIC
    /* Check for the build environment's libudev first */
    if (_this->udev_handle == NULL) {
        _this->udev_handle = SDL_LoadObject(SDL_UDEV_DYNAMIC);
        if (_this->udev_handle != NULL) {
            retval = SDL_UDEV_load_syms();
            if (retval < 0) {
                SDL_UDEV_UnloadLibrary();
            }
        }
    }
#endif

    if (_this->udev_handle == NULL) {
        for( i = 0 ; i < SDL_arraysize(SDL_UDEV_LIBS); i++) {
            _this->udev_handle = SDL_LoadObject(SDL_UDEV_LIBS[i]);
            if (_this->udev_handle != NULL) {
                retval = SDL_UDEV_load_syms();
                if (retval < 0) {
                    SDL_UDEV_UnloadLibrary();
                }
                else {
                    break;
                }
            }
        }
        
        if (_this->udev_handle == NULL) {
            retval = -1;
            /* Don't call SDL_SetError(): SDL_LoadObject already did. */
        }
    }

    return retval;
}

static void get_caps(struct udev_device *dev, struct udev_device *pdev, const char *attr, unsigned long *bitmask, size_t bitmask_len)
{
    const char *value;
    char text[4096];
    char *word;
    int i;
    unsigned long v;

    SDL_memset(bitmask, 0, bitmask_len*sizeof(*bitmask));
    value = _this->syms.udev_device_get_sysattr_value(pdev, attr);
    if (!value) {
        return;
    }

    SDL_strlcpy(text, value, sizeof(text));
    i = 0;
    while ((word = SDL_strrchr(text, ' ')) != NULL) {
        v = SDL_strtoul(word+1, NULL, 16);
        if (i < bitmask_len) {
            bitmask[i] = v;
        }
        ++i;
        *word = '\0';
    }
    v = SDL_strtoul(text, NULL, 16);
    if (i < bitmask_len) {
        bitmask[i] = v;
    }
}

static int
guess_device_class(struct udev_device *dev)
{
    struct udev_device *pdev;
    unsigned long bitmask_ev[NBITS(EV_MAX)];
    unsigned long bitmask_abs[NBITS(ABS_MAX)];
    unsigned long bitmask_key[NBITS(KEY_MAX)];
    unsigned long bitmask_rel[NBITS(REL_MAX)];

    /* walk up the parental chain until we find the real input device; the
     * argument is very likely a subdevice of this, like eventN */
    pdev = dev;
    while (pdev && !_this->syms.udev_device_get_sysattr_value(pdev, "capabilities/ev")) {
        pdev = _this->syms.udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
    }
    if (!pdev) {
        return 0;
    }

    get_caps(dev, pdev, "capabilities/ev", bitmask_ev, SDL_arraysize(bitmask_ev));
    get_caps(dev, pdev, "capabilities/abs", bitmask_abs, SDL_arraysize(bitmask_abs));
    get_caps(dev, pdev, "capabilities/rel", bitmask_rel, SDL_arraysize(bitmask_rel));
    get_caps(dev, pdev, "capabilities/key", bitmask_key, SDL_arraysize(bitmask_key));

    return SDL_EVDEV_GuessDeviceClass(&bitmask_ev[0],
                                      &bitmask_abs[0],
                                      &bitmask_key[0],
                                      &bitmask_rel[0]);
}

static void 
device_event(SDL_UDEV_deviceevent type, struct udev_device *dev) 
{
    const char *subsystem;
    const char *val = NULL;
    int devclass = 0;
    const char *path;
    SDL_UDEV_CallbackList *item;
    
    path = _this->syms.udev_device_get_devnode(dev);
    if (path == NULL) {
        return;
    }
    
    subsystem = _this->syms.udev_device_get_subsystem(dev);
    if (SDL_strcmp(subsystem, "sound") == 0) {
        devclass = SDL_UDEV_DEVICE_SOUND;
    } else if (SDL_strcmp(subsystem, "input") == 0) {
        /* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */
        
        val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK");
        if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
            devclass |= SDL_UDEV_DEVICE_JOYSTICK;
        }

        val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER");
        if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE) &&
            val != NULL && SDL_strcmp(val, "1") == 0 ) {
            devclass |= SDL_UDEV_DEVICE_JOYSTICK;
	}
        
        val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_MOUSE");
        if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
            devclass |= SDL_UDEV_DEVICE_MOUSE;
        }
        
        val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN");
        if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
            devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
        }

        /* The undocumented rule is:
           - All devices with keys get ID_INPUT_KEY
           - From this subset, if they have ESC, numbers, and Q to D, it also gets ID_INPUT_KEYBOARD
           
           Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183
        */
        val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY");
        if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
            devclass |= SDL_UDEV_DEVICE_KEYBOARD;
        }

        if (devclass == 0) {
            /* Fall back to old style input classes */
            val = _this->syms.udev_device_get_property_value(dev, "ID_CLASS");
            if (val != NULL) {
                if (SDL_strcmp(val, "joystick") == 0) {
                    devclass = SDL_UDEV_DEVICE_JOYSTICK;
                } else if (SDL_strcmp(val, "mouse") == 0) {
                    devclass = SDL_UDEV_DEVICE_MOUSE;
                } else if (SDL_strcmp(val, "kbd") == 0) {
                    devclass = SDL_UDEV_DEVICE_KEYBOARD;
                } else {
                    return;
                }
            } else {
                /* We could be linked with libudev on a system that doesn't have udev running */
                devclass = guess_device_class(dev);
            }
        }
    } else {
        return;
    }
    
    /* Process callbacks */
    for (item = _this->first; item != NULL; item = item->next) {
        item->callback(type, devclass, path);
    }
}

void 
SDL_UDEV_Poll(void)
{
    struct udev_device *dev = NULL;
    const char *action = NULL;

    if (_this == NULL) {
        return;
    }

    while (SDL_UDEV_hotplug_update_available()) {
        dev = _this->syms.udev_monitor_receive_device(_this->udev_mon);
        if (dev == NULL) {
            break;
        }
        action = _this->syms.udev_device_get_action(dev);

        if (SDL_strcmp(action, "add") == 0) {
            /* Wait for the device to finish initialization */
            SDL_Delay(100);

            device_event(SDL_UDEV_DEVICEADDED, dev);
        } else if (SDL_strcmp(action, "remove") == 0) {
            device_event(SDL_UDEV_DEVICEREMOVED, dev);
        }
        
        _this->syms.udev_device_unref(dev);
    }
}

int 
SDL_UDEV_AddCallback(SDL_UDEV_Callback cb)
{
    SDL_UDEV_CallbackList *item;
    item = (SDL_UDEV_CallbackList *) SDL_calloc(1, sizeof (SDL_UDEV_CallbackList));
    if (item == NULL) {
        return SDL_OutOfMemory();
    }
    
    item->callback = cb;

    if (_this->last == NULL) {
        _this->first = _this->last = item;
    } else {
        _this->last->next = item;
        _this->last = item;
    }
    
    return 1;
}

void 
SDL_UDEV_DelCallback(SDL_UDEV_Callback cb)
{
    SDL_UDEV_CallbackList *item;
    SDL_UDEV_CallbackList *prev = NULL;

    for (item = _this->first; item != NULL; item = item->next) {
        /* found it, remove it. */
        if (item->callback == cb) {
            if (prev != NULL) {
                prev->next = item->next;
            } else {
                SDL_assert(_this->first == item);
                _this->first = item->next;
            }
            if (item == _this->last) {
                _this->last = prev;
            }
            SDL_free(item);
            return;
        }
        prev = item;
    }
    
}

const SDL_UDEV_Symbols *
SDL_UDEV_GetUdevSyms(void)
{
    if (SDL_UDEV_Init() < 0) {
        SDL_SetError("Could not initialize UDEV");
        return NULL;
    }

    return &_this->syms;
}

void
SDL_UDEV_ReleaseUdevSyms(void)
{
    SDL_UDEV_Quit();
}

#endif /* SDL_USE_LIBUDEV */

/* vi: set ts=4 sw=4 expandtab: */
