/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** 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 <QtCore/qcoreapplication.h>
#include <QtCore/qdebug.h>
#include <QtCore/qmath.h>
#include <private/qaudiohelpers_p.h>

#include "qaudiooutput_pulse.h"
#include "qaudiodeviceinfo_pulse.h"
#include "qpulseaudioengine.h"
#include "qpulsehelpers.h"
#include <sys/types.h>
#include <unistd.h>

QT_BEGIN_NAMESPACE

const int PeriodTimeMs = 20;
const int LowLatencyPeriodTimeMs = 10;
const int LowLatencyBufferSizeMs = 40;

#define LOW_LATENCY_CATEGORY_NAME "game"

static void  outputStreamWriteCallback(pa_stream *stream, size_t length, void *userdata)
{
    Q_UNUSED(stream);
    Q_UNUSED(length);
    Q_UNUSED(userdata);
    QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
    pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
}

static void outputStreamStateCallback(pa_stream *stream, void *userdata)
{
    Q_UNUSED(userdata)
    pa_stream_state_t state = pa_stream_get_state(stream);
#ifdef DEBUG_PULSE
    qDebug() << "Stream state: " << QPulseAudioInternal::stateToQString(state);
#endif
    switch (state) {
        case PA_STREAM_CREATING:
        case PA_STREAM_READY:
        case PA_STREAM_TERMINATED:
            break;

        case PA_STREAM_FAILED:
        default:
            qWarning() << QString("Stream error: %1").arg(pa_strerror(pa_context_errno(pa_stream_get_context(stream))));
            QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
            pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
            break;
    }
}

static void outputStreamUnderflowCallback(pa_stream *stream, void *userdata)
{
    Q_UNUSED(stream)
    ((QPulseAudioOutput*)userdata)->streamUnderflowCallback();
}

static void outputStreamOverflowCallback(pa_stream *stream, void *userdata)
{
    Q_UNUSED(stream)
    Q_UNUSED(userdata)
    qWarning() << "Got a buffer overflow!";
}

static void outputStreamLatencyCallback(pa_stream *stream, void *userdata)
{
    Q_UNUSED(stream)
    Q_UNUSED(userdata)

#ifdef DEBUG_PULSE
    const pa_timing_info *info = pa_stream_get_timing_info(stream);

    qDebug() << "Write index corrupt: " << info->write_index_corrupt;
    qDebug() << "Write index: " << info->write_index;
    qDebug() << "Read index corrupt: " << info->read_index_corrupt;
    qDebug() << "Read index: " << info->read_index;
    qDebug() << "Sink usec: " << info->sink_usec;
    qDebug() << "Configured sink usec: " << info->configured_sink_usec;
#endif
}

static void outputStreamSuccessCallback(pa_stream *stream, int success, void *userdata)
{
    Q_UNUSED(stream);
    Q_UNUSED(success);
    Q_UNUSED(userdata);

    QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
    pa_threaded_mainloop_signal(pulseEngine->mainloop(), 0);
}

static void outputStreamDrainComplete(pa_stream *stream, int success, void *userdata)
{
    Q_UNUSED(stream);
    Q_UNUSED(success);
    Q_UNUSED(userdata);

#ifdef DEBUG_PULSE
    qDebug() << "Draining completed successfully: " << (bool)success;
#endif
}

static void streamAdjustPrebufferCallback(pa_stream *stream, int success, void *userdata)
{
    Q_UNUSED(stream);
    Q_UNUSED(success);
    Q_UNUSED(userdata);

#ifdef DEBUG_PULSE
    qDebug() << "Adjust prebuffer completed successfully: " << (bool)success;
#endif
}


QPulseAudioOutput::QPulseAudioOutput(const QByteArray &device)
    : m_device(device)
    , m_errorState(QAudio::NoError)
    , m_deviceState(QAudio::StoppedState)
    , m_pullMode(true)
    , m_opened(false)
    , m_audioSource(0)
    , m_periodTime(0)
    , m_stream(0)
    , m_notifyInterval(1000)
    , m_periodSize(0)
    , m_bufferSize(0)
    , m_maxBufferSize(0)
    , m_totalTimeValue(0)
    , m_tickTimer(new QTimer(this))
    , m_audioBuffer(0)
    , m_resuming(false)
    , m_volume(1.0)
{
    connect(m_tickTimer, SIGNAL(timeout()), SLOT(userFeed()));
}

QPulseAudioOutput::~QPulseAudioOutput()
{
    close();
    disconnect(m_tickTimer, SIGNAL(timeout()));
    QCoreApplication::processEvents();
}

void QPulseAudioOutput::setError(QAudio::Error error)
{
    if (m_errorState == error)
        return;

    m_errorState = error;
    emit errorChanged(error);
}

QAudio::Error QPulseAudioOutput::error() const
{
    return m_errorState;
}

void QPulseAudioOutput::setState(QAudio::State state)
{
    if (m_deviceState == state)
        return;

    m_deviceState = state;
    emit stateChanged(state);
}

QAudio::State QPulseAudioOutput::state() const
{
    return m_deviceState;
}

void QPulseAudioOutput::streamUnderflowCallback()
{
    if (m_deviceState != QAudio::IdleState && !m_resuming) {
        setError(QAudio::UnderrunError);
        setState(QAudio::IdleState);
    }
}

void QPulseAudioOutput::start(QIODevice *device)
{
    setState(QAudio::StoppedState);
    setError(QAudio::NoError);

    // Handle change of mode
    if (m_audioSource && !m_pullMode) {
        delete m_audioSource;
    }
    m_audioSource = 0;

    close();

    m_pullMode = true;
    m_audioSource = device;

    if (!open()) {
        m_audioSource = 0;
        return;
    }

    setState(QAudio::ActiveState);
}

QIODevice *QPulseAudioOutput::start()
{
    setState(QAudio::StoppedState);
    setError(QAudio::NoError);

    // Handle change of mode
    if (m_audioSource && !m_pullMode) {
        delete m_audioSource;
    }
    m_audioSource = 0;

    close();

    m_pullMode = false;

    if (!open())
        return nullptr;

    m_audioSource = new PulseOutputPrivate(this);
    m_audioSource->open(QIODevice::WriteOnly|QIODevice::Unbuffered);

    setState(QAudio::IdleState);

    return m_audioSource;
}

bool QPulseAudioOutput::open()
{
    if (m_opened)
        return true;

    QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();

    if (!pulseEngine->context() || pa_context_get_state(pulseEngine->context()) != PA_CONTEXT_READY) {
        setError(QAudio::FatalError);
        setState(QAudio::StoppedState);
        emit stateChanged(m_deviceState);
        return false;
    }

    pa_sample_spec spec = QPulseAudioInternal::audioFormatToSampleSpec(m_format);

    if (!pa_sample_spec_valid(&spec)) {
        setError(QAudio::OpenError);
        setState(QAudio::StoppedState);
        emit stateChanged(m_deviceState);
        return false;
    }

    m_spec = spec;
    m_totalTimeValue = 0;

    if (m_streamName.isNull())
        m_streamName = QString(QLatin1String("QtmPulseStream-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8();

#ifdef DEBUG_PULSE
    qDebug() << "Format: " << QPulseAudioInternal::sampleFormatToQString(spec.format);
    qDebug() << "Rate: " << spec.rate;
    qDebug() << "Channels: " << spec.channels;
    qDebug() << "Frame size: " << pa_frame_size(&spec);
#endif

    pulseEngine->lock();

    qint64 bytesPerSecond = m_format.sampleRate() * m_format.channelCount() * m_format.sampleSize() / 8;

    pa_proplist *propList = pa_proplist_new();
    if (!m_category.isNull())
        pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, m_category.toLatin1().constData());

    static const auto mapName = qEnvironmentVariable("QT_PA_CHANNEL_MAP");
    pa_channel_map_def_t mapDef = PA_CHANNEL_MAP_DEFAULT;
    if (mapName == QLatin1String("ALSA"))
        mapDef = PA_CHANNEL_MAP_ALSA;
    else if (mapName == QLatin1String("AUX"))
        mapDef = PA_CHANNEL_MAP_AUX;
    else if (mapName == QLatin1String("WAVEEX"))
        mapDef = PA_CHANNEL_MAP_WAVEEX;
    else if (mapName == QLatin1String("OSS"))
        mapDef = PA_CHANNEL_MAP_OSS;
    else if (!mapName.isEmpty())
        qWarning() << "Unknown pulse audio channel mapping definition:" << mapName;

    pa_channel_map m;
    auto channelMap = pa_channel_map_init_extend(&m, m_spec.channels, mapDef);
    if (!channelMap)
        qWarning() << "QAudioOutput: pa_channel_map_init_extend() Could not initialize channel map";

    m_stream = pa_stream_new_with_proplist(pulseEngine->context(), m_streamName.constData(), &m_spec, channelMap, propList);
    if (!m_stream) {
        qWarning() << "QAudioOutput: pa_stream_new_with_proplist() failed!";
        pulseEngine->unlock();
        setError(QAudio::OpenError);
        setState(QAudio::StoppedState);
        emit stateChanged(m_deviceState);
        return false;
    }

    pa_proplist_free(propList);

    pa_stream_set_state_callback(m_stream, outputStreamStateCallback, this);
    pa_stream_set_write_callback(m_stream, outputStreamWriteCallback, this);

    pa_stream_set_underflow_callback(m_stream, outputStreamUnderflowCallback, this);
    pa_stream_set_overflow_callback(m_stream, outputStreamOverflowCallback, this);
    pa_stream_set_latency_update_callback(m_stream, outputStreamLatencyCallback, this);

    if (m_bufferSize <= 0 && m_category == LOW_LATENCY_CATEGORY_NAME) {
        m_bufferSize = bytesPerSecond * LowLatencyBufferSizeMs / qint64(1000);
    }

    pa_buffer_attr requestedBuffer;
    requestedBuffer.fragsize = (uint32_t)-1;
    requestedBuffer.maxlength = (uint32_t)-1;
    requestedBuffer.minreq = (uint32_t)-1;
    requestedBuffer.prebuf = (uint32_t)-1;
    requestedBuffer.tlength = m_bufferSize;

    if (pa_stream_connect_playback(m_stream, m_device.data(), (m_bufferSize > 0) ? &requestedBuffer : NULL, (pa_stream_flags_t)0, NULL, NULL) < 0) {
        qWarning() << "pa_stream_connect_playback() failed!";
        pa_stream_unref(m_stream);
        m_stream = 0;
        pulseEngine->unlock();
        setError(QAudio::OpenError);
        setState(QAudio::StoppedState);
        emit stateChanged(m_deviceState);
        return false;
    }

    while (pa_stream_get_state(m_stream) != PA_STREAM_READY)
        pa_threaded_mainloop_wait(pulseEngine->mainloop());

    const pa_buffer_attr *buffer = pa_stream_get_buffer_attr(m_stream);
    m_periodTime = (m_category == LOW_LATENCY_CATEGORY_NAME) ? LowLatencyPeriodTimeMs : PeriodTimeMs;
    m_periodSize = pa_usec_to_bytes(m_periodTime*1000, &m_spec);
    m_bufferSize = buffer->tlength;
    m_maxBufferSize = buffer->maxlength;
    m_audioBuffer = new char[m_maxBufferSize];

    const qint64 streamSize = m_audioSource ? m_audioSource->size() : 0;
    if (m_pullMode && streamSize > 0 && static_cast<qint64>(buffer->prebuf) > streamSize) {
        pa_buffer_attr newBufferAttr;
        newBufferAttr = *buffer;
        newBufferAttr.prebuf = streamSize;
        pa_operation *o = pa_stream_set_buffer_attr(m_stream, &newBufferAttr, streamAdjustPrebufferCallback, NULL);
        if (o)
            pa_operation_unref(o);
    }

#ifdef DEBUG_PULSE
    qDebug() << "Buffering info:";
    qDebug() << "\tMax length: " << buffer->maxlength;
    qDebug() << "\tTarget length: " << buffer->tlength;
    qDebug() << "\tPre-buffering: " << buffer->prebuf;
    qDebug() << "\tMinimum request: " << buffer->minreq;
    qDebug() << "\tFragment size: " << buffer->fragsize;
#endif

    pulseEngine->unlock();

    connect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioOutput::onPulseContextFailed);

    m_opened = true;

    m_tickTimer->start(m_periodTime);

    m_elapsedTimeOffset = 0;
    m_timeStamp.restart();
    m_clockStamp.restart();

    return true;
}

void QPulseAudioOutput::close()
{
    if (!m_opened)
        return;

    m_tickTimer->stop();

    QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();

    if (m_stream) {
        pulseEngine->lock();

        pa_stream_set_state_callback(m_stream, 0, 0);
        pa_stream_set_write_callback(m_stream, 0, 0);
        pa_stream_set_underflow_callback(m_stream, 0, 0);
        pa_stream_set_overflow_callback(m_stream, 0, 0);
        pa_stream_set_latency_update_callback(m_stream, 0, 0);

        pa_operation *o = pa_stream_drain(m_stream, outputStreamDrainComplete, NULL);
        if (o)
            pa_operation_unref(o);

        pa_stream_disconnect(m_stream);
        pa_stream_unref(m_stream);
        m_stream = NULL;

        pulseEngine->unlock();
    }

    disconnect(pulseEngine, &QPulseAudioEngine::contextFailed, this, &QPulseAudioOutput::onPulseContextFailed);

    if (!m_pullMode && m_audioSource) {
        delete m_audioSource;
        m_audioSource = 0;
    }
    m_opened = false;
    if (m_audioBuffer) {
        delete[] m_audioBuffer;
        m_audioBuffer = 0;
    }
}

void QPulseAudioOutput::userFeed()
{
    if (m_deviceState == QAudio::StoppedState || m_deviceState == QAudio::SuspendedState)
        return;

    m_resuming = false;

    if (m_pullMode) {
        int writableSize = bytesFree();
        int chunks = writableSize / m_periodSize;
        if (chunks == 0)
            return;

        int input = m_periodSize; // always request 1 chunk of data from user
        if (input > m_maxBufferSize)
            input = m_maxBufferSize;

        int audioBytesPulled = m_audioSource->read(m_audioBuffer, input);
        Q_ASSERT(audioBytesPulled <= input);
        if (m_audioBuffer && audioBytesPulled > 0) {
            if (audioBytesPulled > input) {
                qWarning() << "QPulseAudioOutput::userFeed() - Invalid audio data size provided from user:"
                           << audioBytesPulled << "should be less than" << input;
                audioBytesPulled = input;
            }
            qint64 bytesWritten = write(m_audioBuffer, audioBytesPulled);
            Q_ASSERT(bytesWritten == audioBytesPulled); //unfinished write should not happen since the data provided is less than writableSize
            Q_UNUSED(bytesWritten);

            if (chunks > 1) {
                // PulseAudio needs more data. Ask for it immediately.
                QMetaObject::invokeMethod(this, "userFeed", Qt::QueuedConnection);
            }
        }
    }

    if (m_deviceState != QAudio::ActiveState)
        return;

    if (m_notifyInterval && (m_timeStamp.elapsed() + m_elapsedTimeOffset) > m_notifyInterval) {
        emit notify();
        m_elapsedTimeOffset = m_timeStamp.restart() + m_elapsedTimeOffset - m_notifyInterval;
    }
}

qint64 QPulseAudioOutput::write(const char *data, qint64 len)
{
    QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();

    pulseEngine->lock();

    len = qMin(len, static_cast<qint64>(pa_stream_writable_size(m_stream)));

    if (m_volume < 1.0f) {
        // Don't use PulseAudio volume, as it might affect all other streams of the same category
        // or even affect the system volume if flat volumes are enabled
        void *dest = NULL;
        size_t nbytes = len;
        if (pa_stream_begin_write(m_stream, &dest, &nbytes) < 0) {
            qWarning("QAudioOutput(pulseaudio): pa_stream_begin_write, error = %s",
                     pa_strerror(pa_context_errno(pulseEngine->context())));
            setError(QAudio::IOError);
            return 0;
        }

        len = int(nbytes);
        QAudioHelperInternal::qMultiplySamples(m_volume, m_format, data, dest, len);
        data = reinterpret_cast<char *>(dest);
    }

    if (pa_stream_write(m_stream, data, len, NULL, 0, PA_SEEK_RELATIVE) < 0) {
        qWarning("QAudioOutput(pulseaudio): pa_stream_write, error = %s",
                 pa_strerror(pa_context_errno(pulseEngine->context())));
        setError(QAudio::IOError);
        return 0;
    }

    pulseEngine->unlock();
    m_totalTimeValue += len;

    setError(QAudio::NoError);
    setState(QAudio::ActiveState);

    return len;
}

void QPulseAudioOutput::stop()
{
    if (m_deviceState == QAudio::StoppedState)
        return;

    close();

    setError(QAudio::NoError);
    setState(QAudio::StoppedState);
}

int QPulseAudioOutput::bytesFree() const
{
    if (m_deviceState != QAudio::ActiveState && m_deviceState != QAudio::IdleState)
        return 0;

    QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
    pulseEngine->lock();
    int writableSize = pa_stream_writable_size(m_stream);
    pulseEngine->unlock();
    return writableSize;
}

int QPulseAudioOutput::periodSize() const
{
    return m_periodSize;
}

void QPulseAudioOutput::setBufferSize(int value)
{
    m_bufferSize = value;
}

int QPulseAudioOutput::bufferSize() const
{
    return m_bufferSize;
}

void QPulseAudioOutput::setNotifyInterval(int ms)
{
    m_notifyInterval = qMax(0, ms);
}

int QPulseAudioOutput::notifyInterval() const
{
    return m_notifyInterval;
}

qint64 QPulseAudioOutput::processedUSecs() const
{
    qint64 result = qint64(1000000) * m_totalTimeValue /
        (m_format.channelCount() * (m_format.sampleSize() / 8)) /
        m_format.sampleRate();

    return result;
}

void QPulseAudioOutput::resume()
{
    if (m_deviceState == QAudio::SuspendedState) {
        m_resuming = true;

        QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();

        pulseEngine->lock();

        pa_operation *operation = pa_stream_cork(m_stream, 0, outputStreamSuccessCallback, NULL);
        pulseEngine->wait(operation);
        pa_operation_unref(operation);

        operation = pa_stream_trigger(m_stream, outputStreamSuccessCallback, NULL);
        pulseEngine->wait(operation);
        pa_operation_unref(operation);

        pulseEngine->unlock();

        m_tickTimer->start(m_periodTime);

        setState(m_pullMode ? QAudio::ActiveState : QAudio::IdleState);
        setError(QAudio::NoError);
    }
}

void QPulseAudioOutput::setFormat(const QAudioFormat &format)
{
    m_format = format;
}

QAudioFormat QPulseAudioOutput::format() const
{
    return m_format;
}

void QPulseAudioOutput::suspend()
{
    if (m_deviceState == QAudio::ActiveState || m_deviceState == QAudio::IdleState) {
        setError(QAudio::NoError);
        setState(QAudio::SuspendedState);

        m_tickTimer->stop();

        QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance();
        pa_operation *operation;

        pulseEngine->lock();

        operation = pa_stream_cork(m_stream, 1, outputStreamSuccessCallback, NULL);
        pulseEngine->wait(operation);
        pa_operation_unref(operation);

        pulseEngine->unlock();
    }
}

qint64 QPulseAudioOutput::elapsedUSecs() const
{
    if (m_deviceState == QAudio::StoppedState)
        return 0;

    return m_clockStamp.elapsed() * qint64(1000);
}

void QPulseAudioOutput::reset()
{
    stop();
}

PulseOutputPrivate::PulseOutputPrivate(QPulseAudioOutput *audio)
{
    m_audioDevice = qobject_cast<QPulseAudioOutput*>(audio);
}

qint64 PulseOutputPrivate::readData(char *data, qint64 len)
{
    Q_UNUSED(data)
    Q_UNUSED(len)

    return 0;
}

qint64 PulseOutputPrivate::writeData(const char *data, qint64 len)
{
    int retry = 0;
    qint64 written = 0;

    if ((m_audioDevice->m_deviceState == QAudio::ActiveState
         || m_audioDevice->m_deviceState == QAudio::IdleState)) {
         while(written < len) {
            int chunk = m_audioDevice->write(data+written, (len-written));
            if (chunk <= 0)
                retry++;
            written+=chunk;
            if (retry > 10)
                return written;
        }
    }

    return written;
}

void QPulseAudioOutput::setVolume(qreal vol)
{
    if (qFuzzyCompare(m_volume, vol))
        return;

    m_volume = qBound(qreal(0), vol, qreal(1));
}

qreal QPulseAudioOutput::volume() const
{
    return m_volume;
}

void QPulseAudioOutput::setCategory(const QString &category)
{
    if (m_category != category) {
        m_category = category;
    }
}

QString QPulseAudioOutput::category() const
{
    return m_category;
}

void QPulseAudioOutput::onPulseContextFailed()
{
    close();

    setError(QAudio::FatalError);
    setState(QAudio::StoppedState);
}

QT_END_NAMESPACE

#include "moc_qaudiooutput_pulse.cpp"
