/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 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.
*/
#include "../../SDL_internal.h"

#ifdef SDL_JOYSTICK_HIDAPI

/* Handle rumble on a separate thread so it doesn't block the application */

#include "SDL_assert.h"
#include "SDL_thread.h"
#include "SDL_hidapijoystick_c.h"
#include "SDL_hidapi_rumble.h"


typedef struct SDL_HIDAPI_RumbleRequest
{
    SDL_HIDAPI_Device *device;
    Uint8 data[USB_PACKET_LENGTH];
    int size;
    struct SDL_HIDAPI_RumbleRequest *prev;

} SDL_HIDAPI_RumbleRequest;

typedef struct SDL_HIDAPI_RumbleContext
{
    volatile SDL_bool running;
    SDL_Thread *thread;
    SDL_mutex *lock;
    SDL_sem *request_sem;
    SDL_HIDAPI_RumbleRequest *requests_head;
    SDL_HIDAPI_RumbleRequest *requests_tail;
} SDL_HIDAPI_RumbleContext;

static SDL_HIDAPI_RumbleContext rumble_context;

static int SDL_HIDAPI_RumbleThread(void *data)
{
    SDL_HIDAPI_RumbleContext *ctx = (SDL_HIDAPI_RumbleContext *)data;

    SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);

    while (ctx->running) {
        SDL_HIDAPI_RumbleRequest *request = NULL;

        SDL_SemWait(ctx->request_sem);

        SDL_LockMutex(ctx->lock);
        request = ctx->requests_tail;
        if (request) {
            if (request == ctx->requests_head) {
                ctx->requests_head = NULL;
            }
            ctx->requests_tail = request->prev;
        }
        SDL_UnlockMutex(ctx->lock);

        if (request) {
            SDL_LockMutex(request->device->dev_lock);
            hid_write(request->device->dev, request->data, request->size);
            SDL_UnlockMutex(request->device->dev_lock);
            (void)SDL_AtomicDecRef(&request->device->rumble_pending);
            SDL_free(request);
        }
    }
    return 0;
}

static void
SDL_HIDAPI_StopRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
{
    ctx->running = SDL_FALSE;

    if (ctx->thread) {
        int result;

        SDL_SemPost(ctx->request_sem);
        SDL_WaitThread(ctx->thread, &result);
        ctx->thread = NULL;
    }

    /* This should always be called with an empty queue */
    SDL_assert(!ctx->requests_head);
    SDL_assert(!ctx->requests_tail);

    if (ctx->request_sem) {
        SDL_DestroySemaphore(ctx->request_sem);
        ctx->request_sem = NULL;
    }

    if (ctx->lock) {
        SDL_DestroyMutex(ctx->lock);
        ctx->lock = NULL;
    }
}

static int
SDL_HIDAPI_StartRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
{
    ctx->lock = SDL_CreateMutex();
    if (!ctx->lock) {
        SDL_HIDAPI_StopRumbleThread(ctx);
        return -1;
    }

    ctx->request_sem = SDL_CreateSemaphore(0);
    if (!ctx->request_sem) {
        SDL_HIDAPI_StopRumbleThread(ctx);
        return -1;
    }

    ctx->running = SDL_TRUE;
    ctx->thread = SDL_CreateThread(SDL_HIDAPI_RumbleThread, "HIDAPI Rumble", ctx);
    if (!ctx->thread) {
        SDL_HIDAPI_StopRumbleThread(ctx);
        return -1;
    }
    return 0;
}

int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size)
{
    SDL_HIDAPI_RumbleContext *ctx = &rumble_context;
    SDL_HIDAPI_RumbleRequest *request;

    if (size > sizeof(request->data)) {
        return SDL_SetError("Couldn't send rumble, size %d is greater than %d", size, sizeof(request->data));
    }

    if (!ctx->running) {
        if (SDL_HIDAPI_StartRumbleThread(ctx) < 0) {
            return -1;
        }
    }

    request = (SDL_HIDAPI_RumbleRequest *)SDL_calloc(1, sizeof(*request));
    if (!request) {
        return SDL_OutOfMemory();
    }
    request->device = device;
    SDL_memcpy(request->data, data, size);
    request->size = size;

    SDL_AtomicIncRef(&device->rumble_pending);
    
    SDL_LockMutex(ctx->lock);
    if (ctx->requests_head) {
        ctx->requests_head->prev = request;
    } else {
        ctx->requests_tail = request;
    }
    ctx->requests_head = request;
    SDL_UnlockMutex(ctx->lock);

    SDL_SemPost(ctx->request_sem);

    return size;
}

void SDL_HIDAPI_QuitRumble()
{
    SDL_HIDAPI_RumbleContext *ctx = &rumble_context;

    if (ctx->running) {
        SDL_HIDAPI_StopRumbleThread(ctx);
    }
}

#endif /* SDL_JOYSTICK_HIDAPI */

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