/****************************************************************************
**
** 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 <private/qgstreamerplayercontrol_p.h>
#include <private/qgstreamerplayersession_p.h>

#include <private/qmediaplaylistnavigator_p.h>
#include <private/qmediaresourcepolicy_p.h>
#include <private/qmediaresourceset_p.h>

#include <QtCore/qdir.h>
#include <QtCore/qsocketnotifier.h>
#include <QtCore/qurl.h>
#include <QtCore/qdebug.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

//#define DEBUG_PLAYBIN

QT_BEGIN_NAMESPACE

QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent)
    : QMediaPlayerControl(parent)
    , m_session(session)
{
    m_resources = QMediaResourcePolicy::createResourceSet<QMediaPlayerResourceSetInterface>();
    Q_ASSERT(m_resources);

    connect(m_session, &QGstreamerPlayerSession::positionChanged, this, &QGstreamerPlayerControl::positionChanged);
    connect(m_session, &QGstreamerPlayerSession::durationChanged, this, &QGstreamerPlayerControl::durationChanged);
    connect(m_session, &QGstreamerPlayerSession::mutedStateChanged, this, &QGstreamerPlayerControl::mutedChanged);
    connect(m_session, &QGstreamerPlayerSession::volumeChanged, this, &QGstreamerPlayerControl::volumeChanged);
    connect(m_session, &QGstreamerPlayerSession::stateChanged, this, &QGstreamerPlayerControl::updateSessionState);
    connect(m_session, &QGstreamerPlayerSession::bufferingProgressChanged, this, &QGstreamerPlayerControl::setBufferProgress);
    connect(m_session, &QGstreamerPlayerSession::playbackFinished, this, &QGstreamerPlayerControl::processEOS);
    connect(m_session, &QGstreamerPlayerSession::audioAvailableChanged, this, &QGstreamerPlayerControl::audioAvailableChanged);
    connect(m_session, &QGstreamerPlayerSession::videoAvailableChanged, this, &QGstreamerPlayerControl::videoAvailableChanged);
    connect(m_session, &QGstreamerPlayerSession::seekableChanged, this, &QGstreamerPlayerControl::seekableChanged);
    connect(m_session, &QGstreamerPlayerSession::error, this, &QGstreamerPlayerControl::error);
    connect(m_session, &QGstreamerPlayerSession::invalidMedia, this, &QGstreamerPlayerControl::handleInvalidMedia);
    connect(m_session, &QGstreamerPlayerSession::playbackRateChanged, this, &QGstreamerPlayerControl::playbackRateChanged);

    connect(m_resources, &QMediaPlayerResourceSetInterface::resourcesGranted, this, &QGstreamerPlayerControl::handleResourcesGranted);
    //denied signal should be queued to have correct state update process,
    //since in playOrPause, when acquire is call on resource set, it may trigger a resourcesDenied signal immediately,
    //so handleResourcesDenied should be processed later, otherwise it will be overwritten by state update later in playOrPause.
    connect(m_resources, &QMediaPlayerResourceSetInterface::resourcesDenied,
            this, &QGstreamerPlayerControl::handleResourcesDenied, Qt::QueuedConnection);
    connect(m_resources, &QMediaPlayerResourceSetInterface::resourcesLost, this, &QGstreamerPlayerControl::handleResourcesLost);
}

QGstreamerPlayerControl::~QGstreamerPlayerControl()
{
    QMediaResourcePolicy::destroyResourceSet(m_resources);
}

QMediaPlayerResourceSetInterface* QGstreamerPlayerControl::resources() const
{
    return m_resources;
}

qint64 QGstreamerPlayerControl::position() const
{
    if (m_mediaStatus == QMediaPlayer::EndOfMedia)
        return m_session->duration();

    return m_pendingSeekPosition != -1 ? m_pendingSeekPosition : m_session->position();
}

qint64 QGstreamerPlayerControl::duration() const
{
    return m_session->duration();
}

QMediaPlayer::State QGstreamerPlayerControl::state() const
{
    return m_currentState;
}

QMediaPlayer::MediaStatus QGstreamerPlayerControl::mediaStatus() const
{
    return m_mediaStatus;
}

int QGstreamerPlayerControl::bufferStatus() const
{
    if (m_bufferProgress == -1) {
        return m_session->state() == QMediaPlayer::StoppedState ? 0 : 100;
    } else
        return m_bufferProgress;
}

int QGstreamerPlayerControl::volume() const
{
    return m_session->volume();
}

bool QGstreamerPlayerControl::isMuted() const
{
    return m_session->isMuted();
}

bool QGstreamerPlayerControl::isSeekable() const
{
    return m_session->isSeekable();
}

QMediaTimeRange QGstreamerPlayerControl::availablePlaybackRanges() const
{
    return m_session->availablePlaybackRanges();
}

qreal QGstreamerPlayerControl::playbackRate() const
{
    return m_session->playbackRate();
}

void QGstreamerPlayerControl::setPlaybackRate(qreal rate)
{
    m_session->setPlaybackRate(rate);
}

void QGstreamerPlayerControl::setPosition(qint64 pos)
{
#ifdef DEBUG_PLAYBIN
    qDebug() << Q_FUNC_INFO << pos/1000.0;
#endif

    pushState();

    if (m_mediaStatus == QMediaPlayer::EndOfMedia) {
        m_mediaStatus = QMediaPlayer::LoadedMedia;
    }

    if (m_currentState == QMediaPlayer::StoppedState) {
        m_pendingSeekPosition = pos;
        emit positionChanged(m_pendingSeekPosition);
    } else if (m_session->isSeekable()) {
        m_session->showPrerollFrames(true);
        m_session->seek(pos);
        m_pendingSeekPosition = -1;
    } else if (m_session->state() == QMediaPlayer::StoppedState) {
        m_pendingSeekPosition = pos;
        emit positionChanged(m_pendingSeekPosition);
    } else if (m_pendingSeekPosition != -1) {
        m_pendingSeekPosition = -1;
        emit positionChanged(m_pendingSeekPosition);
    }

    popAndNotifyState();
}

void QGstreamerPlayerControl::play()
{
#ifdef DEBUG_PLAYBIN
    qDebug() << Q_FUNC_INFO;
#endif
    //m_userRequestedState is needed to know that we need to resume playback when resource-policy
    //regranted the resources after lost, since m_currentState will become paused when resources are
    //lost.
    m_userRequestedState = QMediaPlayer::PlayingState;
    playOrPause(QMediaPlayer::PlayingState);
}

void QGstreamerPlayerControl::pause()
{
#ifdef DEBUG_PLAYBIN
    qDebug() << Q_FUNC_INFO;
#endif
    m_userRequestedState = QMediaPlayer::PausedState;
    // If the playback has not been started yet but pause is requested.
    // Seek to the beginning to show first frame.
    if (m_pendingSeekPosition == -1 && m_session->position() == 0)
        m_pendingSeekPosition = 0;

    playOrPause(QMediaPlayer::PausedState);
}

void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState)
{
    if (m_mediaStatus == QMediaPlayer::NoMedia)
        return;

    pushState();

    if (m_setMediaPending) {
        m_mediaStatus = QMediaPlayer::LoadingMedia;
        setMedia(m_currentResource, m_stream);
    }

    if (m_mediaStatus == QMediaPlayer::EndOfMedia && m_pendingSeekPosition == -1) {
        m_pendingSeekPosition = 0;
    }

    if (!m_resources->isGranted())
        m_resources->acquire();

    if (m_resources->isGranted()) {
        // show prerolled frame if switching from stopped state
        if (m_pendingSeekPosition == -1) {
            m_session->showPrerollFrames(true);
        } else if (m_session->state() == QMediaPlayer::StoppedState) {
            // Don't evaluate the next two conditions.
        } else if (m_session->isSeekable()) {
            m_session->pause();
            m_session->showPrerollFrames(true);
            m_session->seek(m_pendingSeekPosition);
            m_pendingSeekPosition = -1;
        } else {
            m_pendingSeekPosition = -1;
        }

        bool ok = false;

        //To prevent displaying the first video frame when playback is resumed
        //the pipeline is paused instead of playing, seeked to requested position,
        //and after seeking is finished (position updated) playback is restarted
        //with show-preroll-frame enabled.
        if (newState == QMediaPlayer::PlayingState && m_pendingSeekPosition == -1)
            ok = m_session->play();
        else
            ok = m_session->pause();

        if (!ok)
            newState = QMediaPlayer::StoppedState;
    }

    if (m_mediaStatus == QMediaPlayer::InvalidMedia)
        m_mediaStatus = QMediaPlayer::LoadingMedia;

    m_currentState = newState;

    if (m_mediaStatus == QMediaPlayer::EndOfMedia || m_mediaStatus == QMediaPlayer::LoadedMedia) {
        if (m_bufferProgress == -1 || m_bufferProgress == 100)
            m_mediaStatus = QMediaPlayer::BufferedMedia;
        else
            m_mediaStatus = QMediaPlayer::BufferingMedia;
    }

    popAndNotifyState();

    emit positionChanged(position());
}

void QGstreamerPlayerControl::stop()
{
#ifdef DEBUG_PLAYBIN
    qDebug() << Q_FUNC_INFO;
#endif
    m_userRequestedState = QMediaPlayer::StoppedState;

    pushState();

    if (m_currentState != QMediaPlayer::StoppedState) {
        m_currentState = QMediaPlayer::StoppedState;
        m_session->showPrerollFrames(false); // stop showing prerolled frames in stop state
        // Since gst is not going to send GST_STATE_PAUSED
        // when pipeline is already paused,
        // needs to update media status directly.
        if (m_session->state() == QMediaPlayer::PausedState)
            updateMediaStatus();
        else if (m_resources->isGranted())
            m_session->pause();

        if (m_mediaStatus != QMediaPlayer::EndOfMedia) {
            m_pendingSeekPosition = 0;
            emit positionChanged(position());
        }
    }

    popAndNotifyState();
}

void QGstreamerPlayerControl::setVolume(int volume)
{
    m_session->setVolume(volume);
}

void QGstreamerPlayerControl::setMuted(bool muted)
{
    m_session->setMuted(muted);
}

QMediaContent QGstreamerPlayerControl::media() const
{
    return m_currentResource;
}

const QIODevice *QGstreamerPlayerControl::mediaStream() const
{
    return m_stream;
}

void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream)
{
#ifdef DEBUG_PLAYBIN
    qDebug() << Q_FUNC_INFO;
#endif

    pushState();

    m_currentState = QMediaPlayer::StoppedState;
    QMediaContent oldMedia = m_currentResource;
    m_pendingSeekPosition = -1;
    m_session->showPrerollFrames(false); // do not show prerolled frames until pause() or play() explicitly called
    m_setMediaPending = false;

    if (!content.isNull() || stream) {
        if (!m_resources->isGranted())
            m_resources->acquire();
    } else {
        m_resources->release();
    }

    m_session->stop();

    bool userStreamValid = false;

    if (m_bufferProgress != -1) {
        m_bufferProgress = -1;
        emit bufferStatusChanged(0);
    }

    m_currentResource = content;
    m_stream = stream;

    QNetworkRequest request = content.request();

    if (m_stream)
        userStreamValid = stream->isOpen() && m_stream->isReadable();

#if !QT_CONFIG(gstreamer_app)
    m_session->loadFromUri(request);
#else
    if (m_stream) {
        if (userStreamValid){
            m_session->loadFromStream(request, m_stream);
        } else {
            m_mediaStatus = QMediaPlayer::InvalidMedia;
            emit error(QMediaPlayer::FormatError, tr("Attempting to play invalid user stream"));
            if (m_currentState != QMediaPlayer::PlayingState)
                m_resources->release();
            popAndNotifyState();
            return;
        }
    } else
        m_session->loadFromUri(request);
#endif

#if QT_CONFIG(gstreamer_app)
    if (!request.url().isEmpty() || userStreamValid) {
#else
    if (!request.url().isEmpty()) {
#endif
        m_mediaStatus = QMediaPlayer::LoadingMedia;
        m_session->pause();
    } else {
        m_mediaStatus = QMediaPlayer::NoMedia;
        setBufferProgress(0);
    }

    if (m_currentResource != oldMedia)
        emit mediaChanged(m_currentResource);

    emit positionChanged(position());

    if (content.isNull() && !stream)
        m_resources->release();

    popAndNotifyState();
}

void QGstreamerPlayerControl::setVideoOutput(QObject *output)
{
    m_session->setVideoRenderer(output);
}

bool QGstreamerPlayerControl::isAudioAvailable() const
{
    return m_session->isAudioAvailable();
}

bool QGstreamerPlayerControl::isVideoAvailable() const
{
    return m_session->isVideoAvailable();
}

void QGstreamerPlayerControl::updateSessionState(QMediaPlayer::State state)
{
    pushState();

    if (state == QMediaPlayer::StoppedState) {
        m_session->showPrerollFrames(false);
        m_currentState = QMediaPlayer::StoppedState;
    }

    if (state == QMediaPlayer::PausedState && m_currentState != QMediaPlayer::StoppedState) {
        if (m_pendingSeekPosition != -1 && m_session->isSeekable()) {
            m_session->showPrerollFrames(true);
            m_session->seek(m_pendingSeekPosition);
        }
        m_pendingSeekPosition = -1;

        if (m_currentState == QMediaPlayer::PlayingState) {
            if (m_bufferProgress == -1 || m_bufferProgress == 100)
                m_session->play();
        }
    }

    updateMediaStatus();

    popAndNotifyState();
}

void QGstreamerPlayerControl::updateMediaStatus()
{
    //EndOfMedia status should be kept, until reset by pause, play or setMedia
    if (m_mediaStatus == QMediaPlayer::EndOfMedia)
        return;

    pushState();
    QMediaPlayer::MediaStatus oldStatus = m_mediaStatus;

    switch (m_session->state()) {
    case QMediaPlayer::StoppedState:
        if (m_currentResource.isNull())
            m_mediaStatus = QMediaPlayer::NoMedia;
        else if (oldStatus != QMediaPlayer::InvalidMedia)
            m_mediaStatus = QMediaPlayer::LoadingMedia;
        break;

    case QMediaPlayer::PlayingState:
    case QMediaPlayer::PausedState:
        if (m_currentState == QMediaPlayer::StoppedState) {
            m_mediaStatus = QMediaPlayer::LoadedMedia;
        } else {
            if (m_bufferProgress == -1 || m_bufferProgress == 100)
                m_mediaStatus = QMediaPlayer::BufferedMedia;
            else
                m_mediaStatus = QMediaPlayer::StalledMedia;
        }
        break;
    }

    if (m_currentState == QMediaPlayer::PlayingState && !m_resources->isGranted())
        m_mediaStatus = QMediaPlayer::StalledMedia;

    popAndNotifyState();
}

void QGstreamerPlayerControl::processEOS()
{
    pushState();
    m_mediaStatus = QMediaPlayer::EndOfMedia;
    emit positionChanged(position());
    m_session->endOfMediaReset();

    if (m_currentState != QMediaPlayer::StoppedState) {
        m_currentState = QMediaPlayer::StoppedState;
        m_session->showPrerollFrames(false); // stop showing prerolled frames in stop state
    }

    popAndNotifyState();
}

void QGstreamerPlayerControl::setBufferProgress(int progress)
{
    if (m_bufferProgress == progress || m_mediaStatus == QMediaPlayer::NoMedia)
        return;

#ifdef DEBUG_PLAYBIN
    qDebug() << Q_FUNC_INFO << progress;
#endif
    m_bufferProgress = progress;

    if (m_resources->isGranted()) {
        if (m_currentState == QMediaPlayer::PlayingState &&
                m_bufferProgress == 100 &&
                m_session->state() != QMediaPlayer::PlayingState)
            m_session->play();

        if (!m_session->isLiveSource() && m_bufferProgress < 100 &&
                (m_session->state() == QMediaPlayer::PlayingState ||
                 m_session->pendingState() == QMediaPlayer::PlayingState))
            m_session->pause();
    }

    updateMediaStatus();

    emit bufferStatusChanged(m_bufferProgress);
}

void QGstreamerPlayerControl::handleInvalidMedia()
{
    pushState();
    m_mediaStatus = QMediaPlayer::InvalidMedia;
    m_currentState = QMediaPlayer::StoppedState;
    m_setMediaPending = true;
    popAndNotifyState();
}

void QGstreamerPlayerControl::handleResourcesGranted()
{
    pushState();

    //This may be triggered when there is an auto resume
    //from resource-policy, we need to take action according to m_userRequestedState
    //rather than m_currentState
    m_currentState = m_userRequestedState;
    if (m_currentState != QMediaPlayer::StoppedState)
        playOrPause(m_currentState);
    else
        updateMediaStatus();

    popAndNotifyState();
}

void QGstreamerPlayerControl::handleResourcesLost()
{
    //on resource lost the pipeline should be paused
    //player status is changed to paused
    pushState();
    QMediaPlayer::State oldState = m_currentState;

    m_session->pause();

    if (oldState != QMediaPlayer::StoppedState )
        m_currentState = QMediaPlayer::PausedState;

    popAndNotifyState();
}

void QGstreamerPlayerControl::handleResourcesDenied()
{
    //on resource denied the pipeline should stay paused
    //player status is changed to paused
    pushState();

    if (m_currentState != QMediaPlayer::StoppedState )
        m_currentState = QMediaPlayer::PausedState;

    popAndNotifyState();
}

void QGstreamerPlayerControl::pushState()
{
    m_stateStack.push(m_currentState);
    m_mediaStatusStack.push(m_mediaStatus);
}

void QGstreamerPlayerControl::popAndNotifyState()
{
    Q_ASSERT(!m_stateStack.isEmpty());

    QMediaPlayer::State oldState = m_stateStack.pop();
    QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatusStack.pop();

    if (m_stateStack.isEmpty()) {
        if (m_mediaStatus != oldMediaStatus) {
#ifdef DEBUG_PLAYBIN
            qDebug() << "Media status changed:" << m_mediaStatus;
#endif
            emit mediaStatusChanged(m_mediaStatus);
        }

        if (m_currentState != oldState) {
#ifdef DEBUG_PLAYBIN
            qDebug() << "State changed:" << m_currentState;
#endif
            emit stateChanged(m_currentState);
        }
    }
}

QT_END_NAMESPACE
