/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwasapiutils.h"

#include <QtCore/QCoreApplication>
#include <QtCore/private/qeventdispatcher_winrt_p.h>

// For Desktop Win32 support
#ifdef CLASSIC_APP_BUILD
#define Q_OS_WINRT
#endif
#include <QtCore/qfunctions_winrt.h>

#include <QtMultimedia/QAudioDeviceInfo>
#include <Audioclient.h>
#include <windows.devices.enumeration.h>
#include <windows.foundation.collections.h>
#include <windows.media.devices.h>

#include <functional>

using namespace ABI::Windows::Devices::Enumeration;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::Media::Devices;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

#define RETURN_EMPTY_LIST_IF_FAILED(msg) RETURN_IF_FAILED(msg, return QList<QByteArray>())

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(lcMmAudioInterface, "qt.multimedia.audiointerface")
Q_LOGGING_CATEGORY(lcMmUtils, "qt.multimedia.utils")

#ifdef CLASSIC_APP_BUILD
// Opening bracket has to be in the same line as MSVC2013 and 2015 complain on
// different lines otherwise
#pragma warning (suppress: 4273)
HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT()> &delegate, bool waitForRun) {
    Q_UNUSED(waitForRun)
    return delegate();
}
#endif

namespace QWasapiUtils {
struct DeviceMapping {
    QList<QByteArray> outputDeviceNames;
    QList<QString> outputDeviceIds;
    QList<QByteArray> inputDeviceNames;
    QList<QString> inputDeviceIds;
};
Q_GLOBAL_STATIC(DeviceMapping, gMapping)
}

struct CoInitializer
{
    CoInitializer()
    {
        CoInitializeEx(NULL, COINIT_MULTITHREADED);
    }

    ~CoInitializer()
    {
        CoUninitialize();
    }
};

static void CoInitIfNeeded()
{
    static CoInitializer initializer;
}

AudioInterface::AudioInterface()
{
    qCDebug(lcMmAudioInterface) << __FUNCTION__;
    m_currentState = Initialized;
}

AudioInterface::~AudioInterface()
{
    qCDebug(lcMmAudioInterface) << __FUNCTION__;
}

HRESULT AudioInterface::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *op)
{
    qCDebug(lcMmAudioInterface) << __FUNCTION__;

    IUnknown *aInterface;
    HRESULT hr;
    HRESULT hrActivate;
    hr = op->GetActivateResult(&hrActivate, &aInterface);
    if (FAILED(hr) || FAILED(hrActivate)) {
        qCDebug(lcMmAudioInterface) << __FUNCTION__ << "Could not query activate results.";
        m_currentState = Error;
        return hr;
    }

    hr = aInterface->QueryInterface(IID_PPV_ARGS(&m_client));
    if (FAILED(hr)) {
        qCDebug(lcMmAudioInterface) << __FUNCTION__ << "Could not access AudioClient interface.";
        m_currentState = Error;
        return hr;
    }

    WAVEFORMATEX *format;
    hr = m_client->GetMixFormat(&format);
    if (FAILED(hr)) {
        qCDebug(lcMmAudioInterface) << __FUNCTION__ << "Could not get mix format.";
        m_currentState = Error;
        return hr;
    }

    QWasapiUtils::convertFromNativeFormat(format, &m_mixFormat);

    m_currentState = Activated;
    return S_OK;
}

bool QWasapiUtils::convertToNativeFormat(const QAudioFormat &qt, WAVEFORMATEX *native)
{
    if (!native
            || !qt.isValid()
            || qt.codec() != QStringLiteral("audio/pcm")
            || qt.sampleRate() <= 0
            || qt.channelCount() <= 0
            || qt.sampleSize() <= 0
            || qt.byteOrder() != QAudioFormat::LittleEndian) {
        return false;
    }

    native->nSamplesPerSec = qt.sampleRate();
    native->wBitsPerSample = qt.sampleSize();
    native->nChannels = qt.channelCount();
    native->nBlockAlign = (native->wBitsPerSample * native->nChannels) / 8;
    native->nAvgBytesPerSec = native->nBlockAlign * native->nSamplesPerSec;
    native->cbSize = 0;

    if (qt.sampleType() == QAudioFormat::Float)
        native->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    else
        native->wFormatTag = WAVE_FORMAT_PCM;

    return true;
}

bool QWasapiUtils::convertFromNativeFormat(const WAVEFORMATEX *native, QAudioFormat *qt)
{
    if (!native || !qt)
        return false;

    qt->setByteOrder(QAudioFormat::LittleEndian);
    qt->setChannelCount(native->nChannels);
    qt->setCodec(QStringLiteral("audio/pcm"));
    qt->setSampleRate(native->nSamplesPerSec);
    qt->setSampleSize(native->wBitsPerSample);
    qt->setSampleType(native->wFormatTag == WAVE_FORMAT_IEEE_FLOAT ? QAudioFormat::Float : QAudioFormat::SignedInt);

    return true;
}

QByteArray QWasapiUtils::defaultDevice(QAudio::Mode mode)
{
    qCDebug(lcMmUtils) << __FUNCTION__ << mode;

    CoInitIfNeeded();
    QList<QByteArray> &deviceNames = mode == QAudio::AudioInput ? gMapping->inputDeviceNames : gMapping->outputDeviceNames;
    QList<QString> &deviceIds = mode == QAudio::AudioInput ? gMapping->inputDeviceIds : gMapping->outputDeviceIds;
    if (deviceNames.isEmpty() || deviceIds.isEmpty()) // Initialize
        availableDevices(mode);
    if (deviceNames.isEmpty() || deviceIds.isEmpty()) // No audio devices at all
        return QByteArray();

    ComPtr<IMediaDeviceStatics> mediaDeviceStatics;
    HRESULT hr;

    hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_Devices_MediaDevice).Get(), &mediaDeviceStatics);
    Q_ASSERT_SUCCEEDED(hr);

    HString defaultAudioDevice;
    quint32 dADSize = 0;

    if (mode == QAudio::AudioOutput)
        hr = mediaDeviceStatics->GetDefaultAudioRenderId(AudioDeviceRole_Default, defaultAudioDevice.GetAddressOf());
    else
        hr = mediaDeviceStatics->GetDefaultAudioCaptureId(AudioDeviceRole_Default, defaultAudioDevice.GetAddressOf());

    const wchar_t *dadWStr = defaultAudioDevice.GetRawBuffer(&dADSize);
    const QString defaultAudioDeviceId = QString::fromWCharArray(dadWStr, dADSize);
    Q_ASSERT(deviceIds.indexOf(defaultAudioDeviceId) != -1);

    return deviceNames.at(deviceIds.indexOf(defaultAudioDeviceId));
}

QList<QByteArray> QWasapiUtils::availableDevices(QAudio::Mode mode)
{
    qCDebug(lcMmUtils) << __FUNCTION__ << mode;

    CoInitIfNeeded();
    ComPtr<IDeviceInformationStatics> statics;
    HRESULT hr;

    hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Enumeration_DeviceInformation).Get(),
                              &statics);
    Q_ASSERT_SUCCEEDED(hr);

    DeviceClass dc = mode == QAudio::AudioInput ? DeviceClass_AudioCapture : DeviceClass_AudioRender;

    QList<QByteArray> &deviceNames = mode == QAudio::AudioInput ? gMapping->inputDeviceNames : gMapping->outputDeviceNames;
    QList<QString> &deviceIds = mode == QAudio::AudioInput ? gMapping->inputDeviceIds : gMapping->outputDeviceIds;

    // We need to refresh due to plugable devices (ie USB)
    deviceNames.clear();
    deviceIds.clear();

    ComPtr<IAsyncOperation<ABI::Windows::Devices::Enumeration::DeviceInformationCollection *>> op;
    hr = statics->FindAllAsyncDeviceClass(dc, &op );
    RETURN_EMPTY_LIST_IF_FAILED("Could not query audio devices.");

    ComPtr<IVectorView<DeviceInformation *>> resultVector;
    hr = QWinRTFunctions::await(op, resultVector.GetAddressOf());
    RETURN_EMPTY_LIST_IF_FAILED("Could not receive audio device list.");

    quint32 deviceCount;
    hr = resultVector->get_Size(&deviceCount);
    RETURN_EMPTY_LIST_IF_FAILED("Could not access audio device count.");
    qCDebug(lcMmUtils) << "Found " << deviceCount << " audio devices for" << mode;

    for (quint32 i = 0; i < deviceCount; ++i) {
        ComPtr<IDeviceInformation> item;
        hr = resultVector->GetAt(i, &item);
        if (FAILED(hr)) {
            qErrnoWarning(hr, "Could not access audio device item.");
            continue;
        }

        HString hString;
        quint32 size;

        hr = item->get_Name(hString.GetAddressOf());
        if (FAILED(hr)) {
            qErrnoWarning(hr, "Could not access audio device name.");
            continue;
        }
        const wchar_t *nameWStr = hString.GetRawBuffer(&size);
        const QString deviceName = QString::fromWCharArray(nameWStr, size);

        hr = item->get_Id(hString.GetAddressOf());
        if (FAILED(hr)) {
            qErrnoWarning(hr, "Could not access audio device id.");
            continue;
        }
        const wchar_t *idWStr = hString.GetRawBuffer(&size);
        const QString deviceId = QString::fromWCharArray(idWStr, size);

        boolean enabled;
        hr = item->get_IsEnabled(&enabled);
        if (FAILED(hr)) {
            qErrnoWarning(hr, "Could not access audio device enabled.");
            continue;
        }

        qCDebug(lcMmUtils) << "Audio Device:" << deviceName << " ID:" << deviceId
                            << " Enabled:" << enabled;

        deviceNames.append(deviceName.toLocal8Bit());
        deviceIds.append(deviceId);
    }
    return deviceNames;
}

Microsoft::WRL::ComPtr<AudioInterface> QWasapiUtils::createOrGetInterface(const QByteArray &dev, QAudio::Mode mode)
{
    qCDebug(lcMmUtils) << __FUNCTION__ << dev << mode;
    Q_ASSERT((mode == QAudio::AudioInput ? gMapping->inputDeviceNames.indexOf(dev) : gMapping->outputDeviceNames.indexOf(dev)) != -1);
    CoInitIfNeeded();

    Microsoft::WRL::ComPtr<AudioInterface> result;
    HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([dev, mode, &result]() {
        HRESULT hr;
        QString id = mode == QAudio::AudioInput ? gMapping->inputDeviceIds.at(gMapping->inputDeviceNames.indexOf(dev)) :
                                                  gMapping->outputDeviceIds.at(gMapping->outputDeviceNames.indexOf(dev));

        result = Make<AudioInterface>();

        ComPtr<IActivateAudioInterfaceAsyncOperation> op;

        // We cannot use QWinRTFunctions::await here as that will return
        // E_NO_INTERFACE. Instead we leave the lambda and wait for the
        // status to get out of Activating
        result->setState(AudioInterface::Activating);
        hr = ActivateAudioInterfaceAsync(reinterpret_cast<LPCWSTR>(id.utf16()), __uuidof(IAudioClient), NULL, result.Get(), op.GetAddressOf());
        if (FAILED(hr)) {
            qErrnoWarning(hr, "Could not invoke audio interface activation.");
            result->setState(AudioInterface::Error);
        }
        return hr;
    });
    qCDebug(lcMmUtils) << "Activation stated:" << hr;
    while (result->state() == AudioInterface::Activating) {
        QThread::yieldCurrentThread();
    }
    qCDebug(lcMmUtils) << "Activation done:" << hr;
    return result;
}

QT_END_NAMESPACE
