/****************************************************************************
**
** 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 "qwasapiaudioinput.h"
#include "qwasapiutils.h"

#include <QtCore/QMutexLocker>
#include <QtCore/QThread>
#include <QtCore/qfunctions_winrt.h>

#include <Audioclient.h>

using namespace Microsoft::WRL;

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(lcMmAudioInput, "qt.multimedia.audioinput")

class WasapiInputDevicePrivate : public QIODevice
{
    Q_OBJECT
public:
    WasapiInputDevicePrivate(QWasapiAudioInput* input);
    ~WasapiInputDevicePrivate();

    qint64 readData(char* data, qint64 len);
    qint64 writeData(const char* data, qint64 len);

private:
    QWasapiAudioInput *m_input;
};

WasapiInputDevicePrivate::WasapiInputDevicePrivate(QWasapiAudioInput* input)
    : m_input(input)
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
}

WasapiInputDevicePrivate::~WasapiInputDevicePrivate()
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
}

qint64 WasapiInputDevicePrivate::readData(char* data, qint64 len)
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;

    const quint32 channelCount = m_input->m_currentFormat.channelCount();
    const quint32 sampleBytes = m_input->m_currentFormat.sampleSize() / 8;

    const quint32 requestedFrames = len / channelCount / sampleBytes;
    quint32 availableFrames = 0;
    HRESULT hr = m_input->m_capture->GetNextPacketSize(&availableFrames);

    quint32 readFrames = qMin(requestedFrames, availableFrames);
    const qint64 readBytes = readFrames * channelCount * sampleBytes;

    BYTE* buffer;
    DWORD flags;

    QMutexLocker locker(&m_input->m_mutex);

    quint64 devicePosition;
    hr = m_input->m_capture->GetBuffer(&buffer, &readFrames, &flags, &devicePosition, NULL);
    if (hr != S_OK) {
        m_input->m_currentError = QAudio::FatalError;
        emit m_input->errorChanged(m_input->m_currentError);
        hr = m_input->m_capture->ReleaseBuffer(readFrames);
        qCDebug(lcMmAudioInput) << __FUNCTION__ << "Could not acquire input buffer.";
        return 0;
    }
    if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT)) {
        // In case this flag is set, user is supposed to ignore the content
        // of the buffer and manually write silence
        qCDebug(lcMmAudioInput) << __FUNCTION__ << "AUDCLNT_BUFFERFLAGS_SILENT: "
                                << "Ignoring buffer and writing silence.";
        memset(data, 0, readBytes);
    } else {
        memcpy(data, buffer, readBytes);
    }

    hr = m_input->m_capture->ReleaseBuffer(readFrames);
    if (hr != S_OK)
        qFatal("Could not release buffer");

    if (m_input->m_interval && m_input->m_openTime.elapsed() - m_input->m_openTimeOffset > m_input->m_interval) {
        emit m_input->notify();
        m_input->m_openTimeOffset = m_input->m_openTime.elapsed();
    }

    m_input->m_bytesProcessed += readBytes;

    if (m_input->m_currentState != QAudio::ActiveState) {
        m_input->m_currentState = QAudio::ActiveState;
        emit m_input->stateChanged(m_input->m_currentState);
    }
    return readBytes;
}

qint64 WasapiInputDevicePrivate::writeData(const char* data, qint64 len)
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    Q_UNUSED(data)
    Q_UNUSED(len)
    return 0;
}

QWasapiAudioInput::QWasapiAudioInput(const QByteArray &device)
    : m_deviceName(device)
    , m_volumeCache(qreal(1.))
    , m_currentState(QAudio::StoppedState)
    , m_currentError(QAudio::NoError)
    , m_bufferFrames(0)
    , m_bufferBytes(4096)
    , m_eventThread(0)
{
    qCDebug(lcMmAudioInput) << __FUNCTION__ << device;
    Q_UNUSED(device)
}

QWasapiAudioInput::~QWasapiAudioInput()
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    stop();
}

void QWasapiAudioInput::setVolume(qreal vol)
{
    qCDebug(lcMmAudioInput) << __FUNCTION__ << vol;
    m_volumeCache = vol;
    if (m_volumeControl) {
        quint32 channelCount;
        HRESULT hr = m_volumeControl->GetChannelCount(&channelCount);
        for (quint32 i = 0; i < channelCount; ++i) {
            hr = m_volumeControl->SetChannelVolume(i, vol);
            RETURN_VOID_IF_FAILED("Could not set audio volume.");
        }
    }
}

qreal QWasapiAudioInput::volume() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    return m_volumeCache;
}

void QWasapiAudioInput::process()
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    DWORD waitRet;

    m_processing = true;
    do {
        waitRet = WaitForSingleObjectEx(m_event, 2000, FALSE);
        if (waitRet != WAIT_OBJECT_0) {
            qFatal("Returned while waiting for event.");
            return;
        }

        QMutexLocker locker(&m_mutex);

        if (m_currentState != QAudio::ActiveState && m_currentState != QAudio::IdleState)
            break;
        QMetaObject::invokeMethod(this, "processBuffer", Qt::QueuedConnection);
    } while (m_processing);
}

void QWasapiAudioInput::processBuffer()
{
    if (!m_pullMode) {
        emit m_eventDevice->readyRead();
        ResetEvent(m_event);
        return;
    }

    QMutexLocker locker(&m_mutex);
    const quint32 channelCount = m_currentFormat.channelCount();
    const quint32 sampleBytes = m_currentFormat.sampleSize() / 8;
    BYTE* buffer;
    HRESULT hr;

    quint32 packetFrames;
    hr = m_capture->GetNextPacketSize(&packetFrames);

    while (packetFrames != 0 && m_currentState == QAudio::ActiveState) {
        DWORD flags;
        quint64 devicePosition;
        hr = m_capture->GetBuffer(&buffer, &packetFrames, &flags, &devicePosition, NULL);
        if (hr != S_OK) {
            m_currentError = QAudio::FatalError;
            emit errorChanged(m_currentError);
            // Also Error Buffers need to be released
            hr = m_capture->ReleaseBuffer(packetFrames);
            qCDebug(lcMmAudioInput) << __FUNCTION__ << "Could not acquire input buffer.";
            return;
        }
        const quint32 writeBytes = packetFrames * channelCount * sampleBytes;
        if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT)) {
            // In case this flag is set, user is supposed to ignore the content
            // of the buffer and manually write silence
            qCDebug(lcMmAudioInput) << __FUNCTION__ << "AUDCLNT_BUFFERFLAGS_SILENT: "
                                    << "Ignoring buffer and writing silence.";
            buffer = new BYTE[writeBytes];
            memset(buffer, 0, writeBytes);
        }

        const qint64 written = m_eventDevice->write(reinterpret_cast<const char *>(buffer), writeBytes);

        if (Q_UNLIKELY(flags & AUDCLNT_BUFFERFLAGS_SILENT))
            delete [] buffer;

        if (written < static_cast<qint64>(writeBytes)) {
            if (m_currentError != QAudio::UnderrunError) {
                m_currentError = QAudio::UnderrunError;
                emit errorChanged(m_currentError);
            }
        }
        hr = m_capture->ReleaseBuffer(packetFrames);
        if (hr != S_OK)
            qFatal("Could not release buffer");

        m_bytesProcessed += writeBytes;

        hr = m_capture->GetNextPacketSize(&packetFrames);
    }
    ResetEvent(m_event);

    if (m_interval && m_openTime.elapsed() - m_openTimeOffset > m_interval) {
        emit notify();
        m_openTimeOffset = m_openTime.elapsed();
    }
    m_processing = m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState;
}

bool QWasapiAudioInput::initStart(bool pull)
{
    if (m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState)
        stop();

    QMutexLocker locker(&m_mutex);

    m_interface = QWasapiUtils::createOrGetInterface(m_deviceName, QAudio::AudioInput);
    Q_ASSERT(m_interface);

    m_pullMode = pull;
    WAVEFORMATEX nFmt;
    WAVEFORMATEX closest;
    WAVEFORMATEX *pClose = &closest;

    if (!m_currentFormat.isValid() || !QWasapiUtils::convertToNativeFormat(m_currentFormat, &nFmt)) {
        m_currentError = QAudio::OpenError;
        emit errorChanged(m_currentError);
        return false;
    }

    HRESULT hr;

    hr = m_interface->m_client->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &nFmt, &pClose);
    if (hr != S_OK) {
        m_currentError = QAudio::OpenError;
        emit errorChanged(m_currentError);
        return false;
    }

    REFERENCE_TIME t = ((10000.0 * 10000 / nFmt.nSamplesPerSec * 1024) + 0.5);
    if (m_bufferBytes)
        t = m_currentFormat.durationForBytes(m_bufferBytes) * 10;

    const DWORD flags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
    hr = m_interface->m_client->Initialize(AUDCLNT_SHAREMODE_SHARED, flags, t, 0, &nFmt, NULL);
    EMIT_RETURN_FALSE_IF_FAILED("Could not initialize audio client.", QAudio::OpenError)

    hr = m_interface->m_client->GetService(IID_PPV_ARGS(&m_capture));
    EMIT_RETURN_FALSE_IF_FAILED("Could not acquire render service.", QAudio::OpenError)

    hr = m_interface->m_client->GetService(IID_PPV_ARGS(&m_volumeControl));
    if (FAILED(hr))
        qCDebug(lcMmAudioInput) << "Could not acquire volume control.";

    hr = m_interface->m_client->GetBufferSize(&m_bufferFrames);
    EMIT_RETURN_FALSE_IF_FAILED("Could not access buffer size.", QAudio::OpenError)

    m_event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
    m_eventThread = new QWasapiProcessThread(this, false);
    m_eventThread->m_event = m_event;
    hr = m_interface->m_client->SetEventHandle(m_event);
    EMIT_RETURN_FALSE_IF_FAILED("Could not set event handle.", QAudio::OpenError)

    if (!m_pullMode) {
        m_eventDevice = new WasapiInputDevicePrivate(this);
        m_eventDevice->open(QIODevice::ReadOnly|QIODevice::Unbuffered);
    }

    hr = m_interface->m_client->Start();
    EMIT_RETURN_FALSE_IF_FAILED("Could not start audio render client.", QAudio::OpenError)

    m_openTime.restart();
    m_openTimeOffset = 0;
    m_bytesProcessed = 0;

    return true;
}

QAudio::Error QWasapiAudioInput::error() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__ << m_currentError;
    return m_currentError;
}

QAudio::State QWasapiAudioInput::state() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    return m_currentState;
}

void QWasapiAudioInput::start(QIODevice* device)
{
    qCDebug(lcMmAudioInput) << __FUNCTION__ << device;
    if (!initStart(true)) {
        qCDebug(lcMmAudioInput) << __FUNCTION__ << "failed";
        return;
    }
    m_eventDevice = device;

    m_mutex.lock();
    m_currentState = QAudio::ActiveState;
    m_mutex.unlock();
    emit stateChanged(m_currentState);
    m_eventThread->start();
}

QIODevice *QWasapiAudioInput::start()
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    if (!initStart(false)) {
        qCDebug(lcMmAudioInput) << __FUNCTION__ << "failed";
        return nullptr;
    }

    m_mutex.lock();
    m_currentState = QAudio::IdleState;
    m_mutex.unlock();
    emit stateChanged(m_currentState);
    m_eventThread->start();
    return m_eventDevice;
}

void QWasapiAudioInput::stop()
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    if (m_currentState == QAudio::StoppedState)
        return;

    m_mutex.lock();
    m_currentState = QAudio::StoppedState;
    m_mutex.unlock();
    emit stateChanged(m_currentState);

    if (m_currentError != QAudio::NoError) {
        m_mutex.lock();
        m_currentError = QAudio::NoError;
        m_mutex.unlock();
        emit errorChanged(m_currentError);
    }

    HRESULT hr = m_interface->m_client->Stop();
    hr = m_interface->m_client->Reset();

    if (m_eventThread) {
        SetEvent(m_eventThread->m_event);
        while (m_eventThread->isRunning())
            QThread::yieldCurrentThread();
        m_eventThread->deleteLater();
        m_eventThread = 0;
    }
}

void QWasapiAudioInput::setFormat(const QAudioFormat& fmt)
{
    qCDebug(lcMmAudioInput) << __FUNCTION__ << fmt;
    if (m_currentState != QAudio::StoppedState)
        return;
    m_currentFormat = fmt;
}

QAudioFormat QWasapiAudioInput::format() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    return m_currentFormat;
}

int QWasapiAudioInput::bytesReady() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    if (m_currentState != QAudio::IdleState && m_currentState != QAudio::ActiveState)
        return 0;

    const quint32 channelCount = m_currentFormat.channelCount();
    const quint32 sampleBytes = m_currentFormat.sampleSize() / 8;

    quint32 packetFrames;
    HRESULT hr = m_capture->GetNextPacketSize(&packetFrames);

    if (FAILED(hr))
        return 0;
    const quint32 writeBytes = packetFrames * channelCount * sampleBytes;

    return writeBytes;
}

void QWasapiAudioInput::resume()
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    if (m_currentState != QAudio::SuspendedState)
        return;

    HRESULT hr = m_interface->m_client->Start();
    EMIT_RETURN_VOID_IF_FAILED("Could not start audio render client.", QAudio::FatalError)

    m_mutex.lock();
    m_currentError = QAudio::NoError;
    m_currentState = QAudio::ActiveState;
    m_mutex.unlock();
    emit stateChanged(m_currentState);
    m_eventThread->start();
}

void QWasapiAudioInput::setBufferSize(int value)
{
    qCDebug(lcMmAudioInput) << __FUNCTION__ << value;
    if (m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState)
        return;
    m_bufferBytes = value;
}

int QWasapiAudioInput::bufferSize() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    if (m_currentState == QAudio::ActiveState || m_currentState == QAudio::IdleState)
        return m_bufferFrames * m_currentFormat.channelCount()* m_currentFormat.sampleSize() / 8;

    return m_bufferBytes;
}

int QWasapiAudioInput::periodSize() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    REFERENCE_TIME defaultDevicePeriod;
    REFERENCE_TIME minimumPeriod;
    HRESULT hr = m_interface->m_client->GetDevicePeriod(&defaultDevicePeriod, &minimumPeriod);
    if (FAILED(hr))
        return 0;
    const int res = m_currentFormat.bytesForDuration(minimumPeriod / 10);
    return res;
}

void QWasapiAudioInput::setNotifyInterval(int ms)
{
    qCDebug(lcMmAudioInput) << __FUNCTION__ << ms;
    m_interval = qMax(0, ms);
}

int QWasapiAudioInput::notifyInterval() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    return m_interval;
}

qint64 QWasapiAudioInput::processedUSecs() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    if (m_currentState == QAudio::StoppedState)
        return 0;
    qint64 res = qint64(1000000) * m_bytesProcessed /
                 (m_currentFormat.channelCount() * (m_currentFormat.sampleSize() / 8)) /
                 m_currentFormat.sampleRate();

    return res;
}

void QWasapiAudioInput::suspend()
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    if (m_currentState != QAudio::ActiveState)
        return;

    m_mutex.lock();
    m_currentState = QAudio::SuspendedState;
    m_mutex.unlock();
    emit stateChanged(m_currentState);

    HRESULT hr = m_interface->m_client->Stop();
    EMIT_RETURN_VOID_IF_FAILED("Could not suspend audio render client.", QAudio::FatalError);

    if (m_eventThread) {
        SetEvent(m_eventThread->m_event);
        while (m_eventThread->isRunning())
            QThread::yieldCurrentThread();
    }
    qCDebug(lcMmAudioInput) << __FUNCTION__ << "Thread has stopped";
}

qint64 QWasapiAudioInput::elapsedUSecs() const
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    if (m_currentState == QAudio::StoppedState)
        return 0;
    return m_openTime.elapsed() * qint64(1000);
}

void QWasapiAudioInput::reset()
{
    qCDebug(lcMmAudioInput) << __FUNCTION__;
    stop();
}

QT_END_NAMESPACE

#include "qwasapiaudioinput.moc"
