/*
  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"

#if SDL_AUDIO_DRIVER_JACK

#include "SDL_assert.h"
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "SDL_jackaudio.h"
#include "SDL_loadso.h"
#include "../../thread/SDL_systhread.h"


static jack_client_t * (*JACK_jack_client_open) (const char *, jack_options_t, jack_status_t *, ...);
static int (*JACK_jack_client_close) (jack_client_t *);
static void (*JACK_jack_on_shutdown) (jack_client_t *, JackShutdownCallback, void *);
static int (*JACK_jack_activate) (jack_client_t *);
static int (*JACK_jack_deactivate) (jack_client_t *);
static void * (*JACK_jack_port_get_buffer) (jack_port_t *, jack_nframes_t);
static int (*JACK_jack_port_unregister) (jack_client_t *, jack_port_t *);
static void (*JACK_jack_free) (void *);
static const char ** (*JACK_jack_get_ports) (jack_client_t *, const char *, const char *, unsigned long);
static jack_nframes_t (*JACK_jack_get_sample_rate) (jack_client_t *);
static jack_nframes_t (*JACK_jack_get_buffer_size) (jack_client_t *);
static jack_port_t * (*JACK_jack_port_register) (jack_client_t *, const char *, const char *, unsigned long, unsigned long);
static jack_port_t * (*JACK_jack_port_by_name) (jack_client_t *, const char *);
static const char * (*JACK_jack_port_name) (const jack_port_t *);
static const char * (*JACK_jack_port_type) (const jack_port_t *);
static int (*JACK_jack_connect) (jack_client_t *, const char *, const char *);
static int (*JACK_jack_set_process_callback) (jack_client_t *, JackProcessCallback, void *);

static int load_jack_syms(void);


#ifdef SDL_AUDIO_DRIVER_JACK_DYNAMIC

static const char *jack_library = SDL_AUDIO_DRIVER_JACK_DYNAMIC;
static void *jack_handle = NULL;

/* !!! FIXME: this is copy/pasted in several places now */
static int
load_jack_sym(const char *fn, void **addr)
{
    *addr = SDL_LoadFunction(jack_handle, fn);
    if (*addr == NULL) {
        /* Don't call SDL_SetError(): SDL_LoadFunction already did. */
        return 0;
    }

    return 1;
}

/* cast funcs to char* first, to please GCC's strict aliasing rules. */
#define SDL_JACK_SYM(x) \
    if (!load_jack_sym(#x, (void **) (char *) &JACK_##x)) return -1

static void
UnloadJackLibrary(void)
{
    if (jack_handle != NULL) {
        SDL_UnloadObject(jack_handle);
        jack_handle = NULL;
    }
}

static int
LoadJackLibrary(void)
{
    int retval = 0;
    if (jack_handle == NULL) {
        jack_handle = SDL_LoadObject(jack_library);
        if (jack_handle == NULL) {
            retval = -1;
            /* Don't call SDL_SetError(): SDL_LoadObject already did. */
        } else {
            retval = load_jack_syms();
            if (retval < 0) {
                UnloadJackLibrary();
            }
        }
    }
    return retval;
}

#else

#define SDL_JACK_SYM(x) JACK_##x = x

static void
UnloadJackLibrary(void)
{
}

static int
LoadJackLibrary(void)
{
    load_jack_syms();
    return 0;
}

#endif /* SDL_AUDIO_DRIVER_JACK_DYNAMIC */


static int
load_jack_syms(void)
{
    SDL_JACK_SYM(jack_client_open);
    SDL_JACK_SYM(jack_client_close);
    SDL_JACK_SYM(jack_on_shutdown);
    SDL_JACK_SYM(jack_activate);
    SDL_JACK_SYM(jack_deactivate);
    SDL_JACK_SYM(jack_port_get_buffer);
    SDL_JACK_SYM(jack_port_unregister);
    SDL_JACK_SYM(jack_free);
    SDL_JACK_SYM(jack_get_ports);
    SDL_JACK_SYM(jack_get_sample_rate);
    SDL_JACK_SYM(jack_get_buffer_size);
    SDL_JACK_SYM(jack_port_register);
    SDL_JACK_SYM(jack_port_by_name);
    SDL_JACK_SYM(jack_port_name);
    SDL_JACK_SYM(jack_port_type);
    SDL_JACK_SYM(jack_connect);
    SDL_JACK_SYM(jack_set_process_callback);
    return 0;
}


static void
jackShutdownCallback(void *arg)  /* JACK went away; device is lost. */
{
    SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
    SDL_OpenedAudioDeviceDisconnected(this);
    SDL_SemPost(this->hidden->iosem);  /* unblock the SDL thread. */
}

// !!! FIXME: implement and register these!
//typedef int(* JackSampleRateCallback)(jack_nframes_t nframes, void *arg)
//typedef int(* JackBufferSizeCallback)(jack_nframes_t nframes, void *arg)

static int
jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg)
{
    SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
    jack_port_t **ports = this->hidden->sdlports;
    const int total_channels = this->spec.channels;
    const int total_frames = this->spec.samples;
    int channelsi;

    if (!SDL_AtomicGet(&this->enabled)) {
        /* silence the buffer to avoid repeats and corruption. */
        SDL_memset(this->hidden->iobuffer, '\0', this->spec.size);
    }

    for (channelsi = 0; channelsi < total_channels; channelsi++) {
        float *dst = (float *) JACK_jack_port_get_buffer(ports[channelsi], nframes);
        if (dst) {
            const float *src = ((float *) this->hidden->iobuffer) + channelsi;
            int framesi;
            for (framesi = 0; framesi < total_frames; framesi++) {
                *(dst++) = *src;
                src += total_channels;
            }
        }
    }

    SDL_SemPost(this->hidden->iosem);  /* tell SDL thread we're done; refill the buffer. */
    return 0;  /* success */
}


/* This function waits until it is possible to write a full sound buffer */
static void
JACK_WaitDevice(_THIS)
{
    if (SDL_AtomicGet(&this->enabled)) {
        if (SDL_SemWait(this->hidden->iosem) == -1) {
            SDL_OpenedAudioDeviceDisconnected(this);
        }
    }
}

static Uint8 *
JACK_GetDeviceBuf(_THIS)
{
    return (Uint8 *) this->hidden->iobuffer;
}


static int
jackProcessCaptureCallback(jack_nframes_t nframes, void *arg)
{
    SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
    if (SDL_AtomicGet(&this->enabled)) {
        jack_port_t **ports = this->hidden->sdlports;
        const int total_channels = this->spec.channels;
        const int total_frames = this->spec.samples;
        int channelsi;
    
        for (channelsi = 0; channelsi < total_channels; channelsi++) {
            const float *src = (const float *) JACK_jack_port_get_buffer(ports[channelsi], nframes);
            if (src) {
                float *dst = ((float *) this->hidden->iobuffer) + channelsi;
                int framesi;
                for (framesi = 0; framesi < total_frames; framesi++) {
                    *dst = *(src++);
                    dst += total_channels;
                }
            }
        }
    }

    SDL_SemPost(this->hidden->iosem);  /* tell SDL thread we're done; new buffer is ready! */
    return 0;  /* success */
}

static int
JACK_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    SDL_assert(buflen == this->spec.size);  /* we always fill a full buffer. */

    /* Wait for JACK to fill the iobuffer */
    if (SDL_SemWait(this->hidden->iosem) == -1) {
        return -1;
    }

    SDL_memcpy(buffer, this->hidden->iobuffer, buflen);
    return buflen;
}

static void
JACK_FlushCapture(_THIS)
{
    SDL_SemWait(this->hidden->iosem);
}


static void
JACK_CloseDevice(_THIS)
{
    if (this->hidden->client) {
        JACK_jack_deactivate(this->hidden->client);

        if (this->hidden->sdlports) {
            const int channels = this->spec.channels;
            int i;
            for (i = 0; i < channels; i++) {
                JACK_jack_port_unregister(this->hidden->client, this->hidden->sdlports[i]);
            }
            SDL_free(this->hidden->sdlports);
        }

        JACK_jack_client_close(this->hidden->client);
    }

    if (this->hidden->iosem) {
        SDL_DestroySemaphore(this->hidden->iosem);
    }

    SDL_free(this->hidden->iobuffer);
    SDL_free(this->hidden);
}

static int
JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    /* Note that JACK uses "output" for capture devices (they output audio
        data to us) and "input" for playback (we input audio data to them).
        Likewise, SDL's playback port will be "output" (we write data out)
        and capture will be "input" (we read data in). */
    const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput;
    const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput;
    const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback;
    const char *sdlportstr = iscapture ? "input" : "output";
    const char **devports = NULL;
    int *audio_ports;
    jack_client_t *client = NULL;
    jack_status_t status;
    int channels = 0;
    int ports = 0;
    int i;

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof (*this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }

    /* !!! FIXME: we _still_ need an API to specify an app name */
    client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
    this->hidden->client = client;
    if (client == NULL) {
        return SDL_SetError("Can't open JACK client");
    }

    devports = JACK_jack_get_ports(client, NULL, NULL, JackPortIsPhysical | sysportflags);
    if (!devports || !devports[0]) {
        return SDL_SetError("No physical JACK ports available");
    }

    while (devports[++ports]) {
        /* spin to count devports */
    }

    /* Filter out non-audio ports */
    audio_ports = SDL_calloc(ports, sizeof *audio_ports);
    for (i = 0; i < ports; i++) {
        const jack_port_t *dport = JACK_jack_port_by_name(client, devports[i]);
        const char *type = JACK_jack_port_type(dport);
        const int len = SDL_strlen(type);
        /* See if type ends with "audio" */
        if (len >= 5 && !SDL_memcmp(type+len-5, "audio", 5)) {
            audio_ports[channels++] = i;
        }
    }
    if (channels == 0) {
        return SDL_SetError("No physical JACK ports available");
    }


    /* !!! FIXME: docs say about buffer size: "This size may change, clients that depend on it must register a bufsize_callback so they will be notified if it does." */

    /* Jack pretty much demands what it wants. */
    this->spec.format = AUDIO_F32SYS;
    this->spec.freq = JACK_jack_get_sample_rate(client);
    this->spec.channels = channels;
    this->spec.samples = JACK_jack_get_buffer_size(client);

    SDL_CalculateAudioSpec(&this->spec);

    this->hidden->iosem = SDL_CreateSemaphore(0);
    if (!this->hidden->iosem) {
        return -1;  /* error was set by SDL_CreateSemaphore */
    }

    this->hidden->iobuffer = (float *) SDL_calloc(1, this->spec.size);
    if (!this->hidden->iobuffer) {
        return SDL_OutOfMemory();
    }

    /* Build SDL's ports, which we will connect to the device ports. */
    this->hidden->sdlports = (jack_port_t **) SDL_calloc(channels, sizeof (jack_port_t *));
    if (this->hidden->sdlports == NULL) {
        return SDL_OutOfMemory();
    }

    for (i = 0; i < channels; i++) {
        char portname[32];
        SDL_snprintf(portname, sizeof (portname), "sdl_jack_%s_%d", sdlportstr, i);
        this->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0);
        if (this->hidden->sdlports[i] == NULL) {
            return SDL_SetError("jack_port_register failed");
        }
    }

    if (JACK_jack_set_process_callback(client, callback, this) != 0) {
        return SDL_SetError("JACK: Couldn't set process callback");
    }

    JACK_jack_on_shutdown(client, jackShutdownCallback, this);

    if (JACK_jack_activate(client) != 0) {
        return SDL_SetError("Failed to activate JACK client");
    }

    /* once activated, we can connect all the ports. */
    for (i = 0; i < channels; i++) {
        const char *sdlport = JACK_jack_port_name(this->hidden->sdlports[i]);
        const char *srcport = iscapture ? devports[audio_ports[i]] : sdlport;
        const char *dstport = iscapture ? sdlport : devports[audio_ports[i]];
        if (JACK_jack_connect(client, srcport, dstport) != 0) {
            return SDL_SetError("Couldn't connect JACK ports: %s => %s", srcport, dstport);
        }
    }

    /* don't need these anymore. */
    JACK_jack_free(devports);
    SDL_free(audio_ports);

    /* We're ready to rock and roll. :-) */
    return 0;
}

static void
JACK_Deinitialize(void)
{
    UnloadJackLibrary();
}

static int
JACK_Init(SDL_AudioDriverImpl * impl)
{
    if (LoadJackLibrary() < 0) {
        return 0;
    } else {
        /* Make sure a JACK server is running and available. */
        jack_status_t status;
        jack_client_t *client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
        if (client == NULL) {
            UnloadJackLibrary();
            return 0;
        }
        JACK_jack_client_close(client);
    }

    /* Set the function pointers */
    impl->OpenDevice = JACK_OpenDevice;
    impl->WaitDevice = JACK_WaitDevice;
    impl->GetDeviceBuf = JACK_GetDeviceBuf;
    impl->CloseDevice = JACK_CloseDevice;
    impl->Deinitialize = JACK_Deinitialize;
    impl->CaptureFromDevice = JACK_CaptureFromDevice;
    impl->FlushCapture = JACK_FlushCapture;
    impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
    impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
    impl->HasCaptureSupport = SDL_TRUE;

    return 1;   /* this audio target is available. */
}

AudioBootStrap JACK_bootstrap = {
    "jack", "JACK Audio Connection Kit", JACK_Init, 0
};

#endif /* SDL_AUDIO_DRIVER_JACK */

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