/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2019 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_NAS

/* Allow access to a raw mixing buffer */

#include <signal.h>
#include <unistd.h>

#include "SDL_timer.h"
#include "SDL_audio.h"
#include "SDL_loadso.h"
#include "../SDL_audio_c.h"
#include "SDL_nasaudio.h"

static void (*NAS_AuCloseServer) (AuServer *);
static void (*NAS_AuNextEvent) (AuServer *, AuBool, AuEvent *);
static AuBool(*NAS_AuDispatchEvent) (AuServer *, AuEvent *);
static void (*NAS_AuHandleEvents) (AuServer *);
static AuFlowID(*NAS_AuCreateFlow) (AuServer *, AuStatus *);
static void (*NAS_AuStartFlow) (AuServer *, AuFlowID, AuStatus *);
static void (*NAS_AuSetElements)
  (AuServer *, AuFlowID, AuBool, int, AuElement *, AuStatus *);
static void (*NAS_AuWriteElement)
  (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuBool, AuStatus *);
static AuUint32 (*NAS_AuReadElement)
  (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuStatus *);
static AuServer *(*NAS_AuOpenServer)
  (_AuConst char *, int, _AuConst char *, int, _AuConst char *, char **);
static AuEventHandlerRec *(*NAS_AuRegisterEventHandler)
  (AuServer *, AuMask, int, AuID, AuEventHandlerCallback, AuPointer);


#ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC

static const char *nas_library = SDL_AUDIO_DRIVER_NAS_DYNAMIC;
static void *nas_handle = NULL;

static int
load_nas_sym(const char *fn, void **addr)
{
    *addr = SDL_LoadFunction(nas_handle, fn);
    if (*addr == NULL) {
        return 0;
    }
    return 1;
}

/* cast funcs to char* first, to please GCC's strict aliasing rules. */
#define SDL_NAS_SYM(x) \
    if (!load_nas_sym(#x, (void **) (char *) &NAS_##x)) return -1
#else
#define SDL_NAS_SYM(x) NAS_##x = x
#endif

static int
load_nas_syms(void)
{
    SDL_NAS_SYM(AuCloseServer);
    SDL_NAS_SYM(AuNextEvent);
    SDL_NAS_SYM(AuDispatchEvent);
    SDL_NAS_SYM(AuHandleEvents);
    SDL_NAS_SYM(AuCreateFlow);
    SDL_NAS_SYM(AuStartFlow);
    SDL_NAS_SYM(AuSetElements);
    SDL_NAS_SYM(AuWriteElement);
    SDL_NAS_SYM(AuReadElement);
    SDL_NAS_SYM(AuOpenServer);
    SDL_NAS_SYM(AuRegisterEventHandler);
    return 0;
}

#undef SDL_NAS_SYM

#ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC

static void
UnloadNASLibrary(void)
{
    if (nas_handle != NULL) {
        SDL_UnloadObject(nas_handle);
        nas_handle = NULL;
    }
}

static int
LoadNASLibrary(void)
{
    int retval = 0;
    if (nas_handle == NULL) {
        nas_handle = SDL_LoadObject(nas_library);
        if (nas_handle == NULL) {
            /* Copy error string so we can use it in a new SDL_SetError(). */
            const char *origerr = SDL_GetError();
            const size_t len = SDL_strlen(origerr) + 1;
            char *err = (char *) alloca(len);
            SDL_strlcpy(err, origerr, len);
            retval = -1;
            SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s",
                         nas_library, err);
        } else {
            retval = load_nas_syms();
            if (retval < 0) {
                UnloadNASLibrary();
            }
        }
    }
    return retval;
}

#else

static void
UnloadNASLibrary(void)
{
}

static int
LoadNASLibrary(void)
{
    load_nas_syms();
    return 0;
}

#endif /* SDL_AUDIO_DRIVER_NAS_DYNAMIC */

/* This function waits until it is possible to write a full sound buffer */
static void
NAS_WaitDevice(_THIS)
{
    while (this->hidden->buf_free < this->hidden->mixlen) {
        AuEvent ev;
        NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev);
        NAS_AuDispatchEvent(this->hidden->aud, &ev);
    }
}

static void
NAS_PlayDevice(_THIS)
{
    while (this->hidden->mixlen > this->hidden->buf_free) {
        /*
         * We think the buffer is full? Yikes! Ask the server for events,
         *  in the hope that some of them is LowWater events telling us more
         *  of the buffer is free now than what we think.
         */
        AuEvent ev;
        NAS_AuNextEvent(this->hidden->aud, AuTrue, &ev);
        NAS_AuDispatchEvent(this->hidden->aud, &ev);
    }
    this->hidden->buf_free -= this->hidden->mixlen;

    /* Write the audio data */
    NAS_AuWriteElement(this->hidden->aud, this->hidden->flow, 0,
                       this->hidden->mixlen, this->hidden->mixbuf, AuFalse,
                       NULL);

    this->hidden->written += this->hidden->mixlen;

#ifdef DEBUG_AUDIO
    fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen);
#endif
}

static Uint8 *
NAS_GetDeviceBuf(_THIS)
{
    return (this->hidden->mixbuf);
}

static int
NAS_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    struct SDL_PrivateAudioData *h = this->hidden;
    int retval;

    while (SDL_TRUE) {
        /* just keep the event queue moving and the server chattering. */
        NAS_AuHandleEvents(h->aud);
    
        retval = (int) NAS_AuReadElement(h->aud, h->flow, 1, buflen, buffer, NULL);
        /*printf("read %d capture bytes\n", (int) retval);*/
        if (retval == 0) {
            SDL_Delay(10);  /* don't burn the CPU if we're waiting for data. */
        } else {
            break;
        }
    }

    return retval;
}

static void
NAS_FlushCapture(_THIS)
{
    struct SDL_PrivateAudioData *h = this->hidden;
    AuUint32 total = 0;
    AuUint32 br;
    Uint8 buf[512];

    do {
        /* just keep the event queue moving and the server chattering. */
        NAS_AuHandleEvents(h->aud);
        br = NAS_AuReadElement(h->aud, h->flow, 1, sizeof (buf), buf, NULL);
        /*printf("flushed %d capture bytes\n", (int) br);*/
        total += br;
    } while ((br == sizeof (buf)) && (total < this->spec.size));
}

static void
NAS_CloseDevice(_THIS)
{
    if (this->hidden->aud) {
        NAS_AuCloseServer(this->hidden->aud);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}

static unsigned char
sdlformat_to_auformat(unsigned int fmt)
{
    switch (fmt) {
    case AUDIO_U8:
        return AuFormatLinearUnsigned8;
    case AUDIO_S8:
        return AuFormatLinearSigned8;
    case AUDIO_U16LSB:
        return AuFormatLinearUnsigned16LSB;
    case AUDIO_U16MSB:
        return AuFormatLinearUnsigned16MSB;
    case AUDIO_S16LSB:
        return AuFormatLinearSigned16LSB;
    case AUDIO_S16MSB:
        return AuFormatLinearSigned16MSB;
    }
    return AuNone;
}

static AuBool
event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd)
{
    SDL_AudioDevice *this = (SDL_AudioDevice *) hnd->data;
    struct SDL_PrivateAudioData *h = this->hidden;
    if (this->iscapture) {
        return AuTrue;  /* we don't (currently) care about any of this for capture devices */
    }

    switch (ev->type) {
    case AuEventTypeElementNotify:
        {
            AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev;

            switch (event->kind) {
            case AuElementNotifyKindLowWater:
                if (h->buf_free >= 0) {
                    h->really += event->num_bytes;
                    gettimeofday(&h->last_tv, 0);
                    h->buf_free += event->num_bytes;
                } else {
                    h->buf_free = event->num_bytes;
                }
                break;
            case AuElementNotifyKindState:
                switch (event->cur_state) {
                case AuStatePause:
                    if (event->reason != AuReasonUser) {
                        if (h->buf_free >= 0) {
                            h->really += event->num_bytes;
                            gettimeofday(&h->last_tv, 0);
                            h->buf_free += event->num_bytes;
                        } else {
                            h->buf_free = event->num_bytes;
                        }
                    }
                    break;
                }
            }
        }
    }
    return AuTrue;
}

static AuDeviceID
find_device(_THIS)
{
    /* These "Au" things are all macros, not functions... */
    struct SDL_PrivateAudioData *h = this->hidden;
    const unsigned int devicekind = this->iscapture ? AuComponentKindPhysicalInput : AuComponentKindPhysicalOutput;
    const int numdevs = AuServerNumDevices(h->aud);
    const int nch = this->spec.channels;
    int i;

    /* Try to find exact match on channels first... */
    for (i = 0; i < numdevs; i++) {
        const AuDeviceAttributes *dev = AuServerDevice(h->aud, i);
        if ((AuDeviceKind(dev) == devicekind) && (AuDeviceNumTracks(dev) == nch)) {
            return AuDeviceIdentifier(dev);
        }
    }

    /* Take anything, then... */
    for (i = 0; i < numdevs; i++) {
        const AuDeviceAttributes *dev = AuServerDevice(h->aud, i);
        if (AuDeviceKind(dev) == devicekind) {
            this->spec.channels = AuDeviceNumTracks(dev);
            return AuDeviceIdentifier(dev);
        }
    }
    return AuNone;
}

static int
NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    AuElement elms[3];
    int buffer_size;
    SDL_AudioFormat test_format, format;

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

    /* Try for a closest match on audio format */
    format = 0;
    for (test_format = SDL_FirstAudioFormat(this->spec.format);
         !format && test_format;) {
        format = sdlformat_to_auformat(test_format);
        if (format == AuNone) {
            test_format = SDL_NextAudioFormat();
        }
    }
    if (format == 0) {
        return SDL_SetError("NAS: Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;

    this->hidden->aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
    if (this->hidden->aud == 0) {
        return SDL_SetError("NAS: Couldn't open connection to NAS server");
    }

    this->hidden->dev = find_device(this);
    if ((this->hidden->dev == AuNone)
        || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, 0)))) {
        return SDL_SetError("NAS: Couldn't find a fitting device on NAS server");
    }

    buffer_size = this->spec.freq;
    if (buffer_size < 4096)
        buffer_size = 4096;

    if (buffer_size > 32768)
        buffer_size = 32768;    /* So that the buffer won't get unmanageably big. */

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);

    if (iscapture) {
        AuMakeElementImportDevice(elms, this->spec.freq, this->hidden->dev,
                                  AuUnlimitedSamples, 0, NULL);
        AuMakeElementExportClient(elms + 1, 0, this->spec.freq, format,
                                  this->spec.channels, AuTrue, buffer_size,
                                  buffer_size, 0, NULL);
    } else {
        AuMakeElementImportClient(elms, this->spec.freq, format,
                                  this->spec.channels, AuTrue, buffer_size,
                                  buffer_size / 4, 0, NULL);
        AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq,
                                  AuUnlimitedSamples, 0, NULL);
    }

    NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue,
                      2, elms, NULL);

    NAS_AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0,
                               this->hidden->flow, event_handler,
                               (AuPointer) this);

    NAS_AuStartFlow(this->hidden->aud, this->hidden->flow, NULL);

    /* Allocate mixing buffer */
    if (!iscapture) {
        this->hidden->mixlen = this->spec.size;
        this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
        if (this->hidden->mixbuf == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    }

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

static void
NAS_Deinitialize(void)
{
    UnloadNASLibrary();
}

static int
NAS_Init(SDL_AudioDriverImpl * impl)
{
    if (LoadNASLibrary() < 0) {
        return 0;
    } else {
        AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
        if (aud == NULL) {
            SDL_SetError("NAS: AuOpenServer() failed (no audio server?)");
            return 0;
        }
        NAS_AuCloseServer(aud);
    }

    /* Set the function pointers */
    impl->OpenDevice = NAS_OpenDevice;
    impl->PlayDevice = NAS_PlayDevice;
    impl->WaitDevice = NAS_WaitDevice;
    impl->GetDeviceBuf = NAS_GetDeviceBuf;
    impl->CaptureFromDevice = NAS_CaptureFromDevice;
    impl->FlushCapture = NAS_FlushCapture;
    impl->CloseDevice = NAS_CloseDevice;
    impl->Deinitialize = NAS_Deinitialize;

    impl->OnlyHasDefaultOutputDevice = 1;
    impl->OnlyHasDefaultCaptureDevice = 1;
    impl->HasCaptureSupport = SDL_TRUE;

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

AudioBootStrap NAS_bootstrap = {
    "nas", "Network Audio System", NAS_Init, 0
};

#endif /* SDL_AUDIO_DRIVER_NAS */

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