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

// This is C++/CX code that the WinRT port uses to talk to WASAPI-related
//  system APIs. The C implementation of these functions, for non-WinRT apps,
//  is in SDL_wasapi_win32.c. The code in SDL_wasapi.c is used by both standard
//  Windows and WinRT builds to deal with audio and calls into these functions.

#if SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)

#include <Windows.h>
#include <windows.ui.core.h>
#include <windows.devices.enumeration.h>
#include <windows.media.devices.h>
#include <wrl/implements.h>

extern "C" {
#include "../../core/windows/SDL_windows.h"
#include "SDL_audio.h"
#include "SDL_timer.h"
#include "../SDL_audio_c.h"
#include "../SDL_sysaudio.h"
#include "SDL_assert.h"
}

#define COBJMACROS
#include <mmdeviceapi.h>
#include <audioclient.h>

#include "SDL_wasapi.h"

using namespace Windows::Devices::Enumeration;
using namespace Windows::Media::Devices;
using namespace Windows::Foundation;
using namespace Microsoft::WRL;

class SDL_WasapiDeviceEventHandler
{
public:
    SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture);
    ~SDL_WasapiDeviceEventHandler();
    void OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ args);
    void OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ args);
    void OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args);
    void OnEnumerationCompleted(DeviceWatcher^ sender, Platform::Object^ args);
    void OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args);
    void OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args);
    SDL_semaphore* completed;

private:
    const SDL_bool iscapture;
    DeviceWatcher^ watcher;
    Windows::Foundation::EventRegistrationToken added_handler;
    Windows::Foundation::EventRegistrationToken removed_handler;
    Windows::Foundation::EventRegistrationToken updated_handler;
    Windows::Foundation::EventRegistrationToken completed_handler;
    Windows::Foundation::EventRegistrationToken default_changed_handler;
};

SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture)
    : iscapture(_iscapture)
    , completed(SDL_CreateSemaphore(0))
    , watcher(DeviceInformation::CreateWatcher(_iscapture ? DeviceClass::AudioCapture : DeviceClass::AudioRender))
{
    if (!watcher || !completed)
        return;  // uhoh.

    // !!! FIXME: this doesn't need a lambda here, I think, if I make SDL_WasapiDeviceEventHandler a proper C++/CX class. --ryan.
    added_handler = watcher->Added += ref new TypedEventHandler<DeviceWatcher^, DeviceInformation^>([this](DeviceWatcher^ sender, DeviceInformation^ args) { OnDeviceAdded(sender, args); } );
    removed_handler = watcher->Removed += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceRemoved(sender, args); } );
    updated_handler = watcher->Updated += ref new TypedEventHandler<DeviceWatcher^, DeviceInformationUpdate^>([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceUpdated(sender, args); } );
    completed_handler = watcher->EnumerationCompleted += ref new TypedEventHandler<DeviceWatcher^, Platform::Object^>([this](DeviceWatcher^ sender, Platform::Object^ args) { OnEnumerationCompleted(sender, args); } );
    if (iscapture) {
        default_changed_handler = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioCaptureDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args) { OnDefaultCaptureDeviceChanged(sender, args); } );
    } else {
        default_changed_handler = MediaDevice::DefaultAudioRenderDeviceChanged += ref new TypedEventHandler<Platform::Object^, DefaultAudioRenderDeviceChangedEventArgs^>([this](Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args) { OnDefaultRenderDeviceChanged(sender, args); } );
    }
    watcher->Start();
}

SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler()
{
    if (watcher) {
        watcher->Added -= added_handler;
        watcher->Removed -= removed_handler;
        watcher->Updated -= updated_handler;
        watcher->EnumerationCompleted -= completed_handler;
        watcher->Stop();
        watcher = nullptr;
    }
    if (completed) {
        SDL_DestroySemaphore(completed);
        completed = nullptr;
    }

    if (iscapture) {
        MediaDevice::DefaultAudioCaptureDeviceChanged -= default_changed_handler;
    } else {
        MediaDevice::DefaultAudioRenderDeviceChanged -= default_changed_handler;
    }
}

void
SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ info)
{
    SDL_assert(sender == this->watcher);
    char *utf8dev = WIN_StringToUTF8(info->Name->Data());
    if (utf8dev) {
        WASAPI_AddDevice(this->iscapture, utf8dev, info->Id->Data());
        SDL_free(utf8dev);
    }
}

void
SDL_WasapiDeviceEventHandler::OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ info)
{
    SDL_assert(sender == this->watcher);
    WASAPI_RemoveDevice(this->iscapture, info->Id->Data());
}

void
SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args)
{
    SDL_assert(sender == this->watcher);
}

void
SDL_WasapiDeviceEventHandler::OnEnumerationCompleted(DeviceWatcher^ sender, Platform::Object^ args)
{
    SDL_assert(sender == this->watcher);
    SDL_SemPost(this->completed);
}

void
SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args)
{
    SDL_assert(this->iscapture);
    SDL_AtomicAdd(&WASAPI_DefaultPlaybackGeneration, 1);
}

void
SDL_WasapiDeviceEventHandler::OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args)
{
    SDL_assert(!this->iscapture);
    SDL_AtomicAdd(&WASAPI_DefaultCaptureGeneration, 1);
}


static SDL_WasapiDeviceEventHandler *playback_device_event_handler;
static SDL_WasapiDeviceEventHandler *capture_device_event_handler;

int WASAPI_PlatformInit(void)
{
    return 0;
}

void WASAPI_PlatformDeinit(void)
{
    delete playback_device_event_handler;
    playback_device_event_handler = nullptr;
    delete capture_device_event_handler;
    capture_device_event_handler = nullptr;
}

void WASAPI_EnumerateEndpoints(void)
{
    // DeviceWatchers will fire an Added event for each existing device at
    //  startup, so we don't need to enumerate them separately before
    //  listening for updates.
    playback_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_FALSE);
    capture_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_TRUE);
    SDL_SemWait(playback_device_event_handler->completed);
    SDL_SemWait(capture_device_event_handler->completed);
}

struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >
{
    SDL_WasapiActivationHandler() : device(nullptr) {}
    STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation *operation);
    SDL_AudioDevice *device;
};

HRESULT
SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async)
{
    // Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
    SDL_AtomicSet(&device->hidden->just_activated, 1);
    WASAPI_UnrefDevice(device);
    return S_OK;
}

void
WASAPI_PlatformDeleteActivationHandler(void *handler)
{
    ((SDL_WasapiActivationHandler *) handler)->Release();
}

int
WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
{
    LPCWSTR devid = _this->hidden->devid;
    Platform::String^ defdevid;

    if (devid == nullptr) {
        defdevid = _this->iscapture ? MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default) : MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);
        if (defdevid) {
            devid = defdevid->Data();
        }
    }

    SDL_AtomicSet(&_this->hidden->just_activated, 0);

    ComPtr<SDL_WasapiActivationHandler> handler = Make<SDL_WasapiActivationHandler>();
    if (handler == nullptr) {
        return SDL_SetError("Failed to allocate WASAPI activation handler");
    }

    handler.Get()->AddRef();  // we hold a reference after ComPtr destructs on return, causing a Release, and Release ourselves in WASAPI_PlatformDeleteActivationHandler(), etc.
    handler.Get()->device = _this;
    _this->hidden->activation_handler = handler.Get();

    WASAPI_RefDevice(_this);  /* completion handler will unref it. */
    IActivateAudioInterfaceAsyncOperation *async = nullptr;
    const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);

    if (FAILED(ret) || async == nullptr) {
        if (async != nullptr) {
            async->Release();
        }
        handler.Get()->Release();
        WASAPI_UnrefDevice(_this);
        return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
    }

    /* Spin until the async operation is complete.
     * If we don't PrepDevice before leaving this function, the bug list gets LONG:
     * - device.spec is not filled with the correct information
     * - The 'obtained' spec will be wrong for ALLOW_CHANGE properties
     * - SDL_AudioStreams will/will not be allocated at the right time
     * - SDL_assert(device->callbackspec.size == device->spec.size) will fail
     * - When the assert is ignored, skipping or a buffer overflow will occur
     */
    while (!SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
        SDL_Delay(1);
    }

    HRESULT activateRes = S_OK;
    IUnknown *iunknown = nullptr;
    const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown);
    async->Release();
    if (FAILED(getActivateRes)) {
        return WIN_SetErrorFromHRESULT("Failed to get WASAPI activate result", getActivateRes);
    } else if (FAILED(activateRes)) {
        return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes);
    }

    iunknown->QueryInterface(IID_PPV_ARGS(&_this->hidden->client));
    if (!_this->hidden->client) {
        return SDL_SetError("Failed to query WASAPI client interface");
    }

    if (WASAPI_PrepDevice(_this, isrecovery) == -1) {
        return -1;
    }

    return 0;
}

void
WASAPI_PlatformThreadInit(_THIS)
{
    // !!! FIXME: set this thread to "Pro Audio" priority.
}

void
WASAPI_PlatformThreadDeinit(_THIS)
{
    // !!! FIXME: set this thread to "Pro Audio" priority.
}

#endif  // SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)

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