/****************************************************************************
**
** 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 "qplaylistfileparser_p.h"
#include <qfileinfo.h>
#include <QtCore/QDebug>
#include <QtCore/qiodevice.h>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include "qmediaplayer.h"
#include "qmediaobject_p.h"
#include "qmediametadata.h"
#include "qmediacontent.h"
#include "qmediaresource.h"

QT_BEGIN_NAMESPACE

namespace {

class ParserBase
{
public:
    explicit ParserBase(QPlaylistFileParser *parent)
        : m_parent(parent)
        , m_aborted(false)
    {
        Q_ASSERT(m_parent);
    }

    bool parseLine(int lineIndex, const QString& line, const QUrl& root)
    {
        if (m_aborted)
            return false;

        const bool ok = parseLineImpl(lineIndex, line, root);
        return ok && !m_aborted;
    }

    virtual void abort() { m_aborted = true; }
    virtual ~ParserBase() { }

protected:
    virtual bool parseLineImpl(int lineIndex, const QString& line, const QUrl& root) = 0;

    static QUrl expandToFullPath(const QUrl &root, const QString &line)
    {
        // On Linux, backslashes are not converted to forward slashes :/
        if (line.startsWith(QLatin1String("//")) || line.startsWith(QLatin1String("\\\\"))) {
            // Network share paths are not resolved
            return QUrl::fromLocalFile(line);
        }

        QUrl url(line);
        if (url.scheme().isEmpty()) {
            // Resolve it relative to root
            if (root.isLocalFile())
                return QUrl::fromUserInput(line, root.adjusted(QUrl::RemoveFilename).toLocalFile(), QUrl::AssumeLocalFile);
            else
                return root.resolved(url);
        } else if (url.scheme().length() == 1) {
            // Assume it's a drive letter for a Windows path
            url = QUrl::fromLocalFile(line);
        }

        return url;
    }

    void newItemFound(const QVariant& content) { Q_EMIT m_parent->newItem(content); }

private:
    QPlaylistFileParser *m_parent;
    bool m_aborted;
};

class M3UParser : public ParserBase
{
public:
    explicit M3UParser(QPlaylistFileParser *q)
        : ParserBase(q)
        , m_extendedFormat(false)
    {
    }

    /*
     *
    Extended M3U directives

    #EXTM3U - header - must be first line of file
    #EXTINF - extra info - length (seconds), title
    #EXTINF - extra info - length (seconds), artist '-' title

    Example

    #EXTM3U
    #EXTINF:123, Sample artist - Sample title
    C:\Documents and Settings\I\My Music\Sample.mp3
    #EXTINF:321,Example Artist - Example title
    C:\Documents and Settings\I\My Music\Greatest Hits\Example.ogg

     */
    bool parseLineImpl(int lineIndex, const QString& line, const QUrl& root) override
    {
        if (line[0] == '#' ) {
            if (m_extendedFormat) {
                if (line.startsWith(QLatin1String("#EXTINF:"))) {
                    m_extraInfo.clear();
                    int artistStart = line.indexOf(QLatin1String(","), 8);
                    bool ok = false;
                    int length = line.midRef(8, artistStart < 8 ? -1 : artistStart - 8).trimmed().toInt(&ok);
                    if (ok && length > 0) {
                        //convert from second to milisecond
                        m_extraInfo[QMediaMetaData::Duration] = QVariant(length * 1000);
                    }
                    if (artistStart > 0) {
                        int titleStart = getSplitIndex(line, artistStart);
                        if (titleStart > artistStart) {
                            m_extraInfo[QMediaMetaData::Author] = line.midRef(artistStart + 1,
                                                             titleStart - artistStart - 1).trimmed().toString().
                                                             replace(QLatin1String("--"), QLatin1String("-"));
                            m_extraInfo[QMediaMetaData::Title] = line.midRef(titleStart + 1).trimmed().toString().
                                                   replace(QLatin1String("--"), QLatin1String("-"));
                        } else {
                            m_extraInfo[QMediaMetaData::Title] = line.midRef(artistStart + 1).trimmed().toString().
                                                   replace(QLatin1String("--"), QLatin1String("-"));
                        }
                    }
                }
            } else if (lineIndex == 0 && line.startsWith(QLatin1String("#EXTM3U"))) {
                m_extendedFormat = true;
            }
        } else {
            m_extraInfo[QLatin1String("url")] = expandToFullPath(root, line);
            newItemFound(QVariant(m_extraInfo));
            m_extraInfo.clear();
        }

        return true;
    }

    int getSplitIndex(const QString& line, int startPos)
    {
        if (startPos < 0)
            startPos = 0;
        const QChar* buf = line.data();
        for (int i = startPos; i < line.length(); ++i) {
            if (buf[i] == '-') {
                if (i == line.length() - 1)
                    return i;
                ++i;
                if (buf[i] != '-')
                    return i - 1;
            }
        }
        return -1;
    }

private:
    QVariantMap     m_extraInfo;
    bool            m_extendedFormat;
};

class PLSParser : public ParserBase
{
public:
    explicit PLSParser(QPlaylistFileParser *q)
        : ParserBase(q)
    {
    }

/*
 *
The format is essentially that of an INI file structured as follows:

Header

    * [playlist] : This tag indicates that it is a Playlist File

Track Entry
Assuming track entry #X

    * FileX : Variable defining location of stream.
    * TitleX : Defines track title.
    * LengthX : Length in seconds of track. Value of -1 indicates indefinite.

Footer

    * NumberOfEntries : This variable indicates the number of tracks.
    * Version : Playlist version. Currently only a value of 2 is valid.

[playlist]

File1=Alternative\everclear - SMFTA.mp3

Title1=Everclear - So Much For The Afterglow

Length1=233

File2=http://www.site.com:8000/listen.pls

Title2=My Cool Stream

Length5=-1

NumberOfEntries=2

Version=2
*/
    bool parseLineImpl(int, const QString &line, const QUrl &root) override
    {
        // We ignore everything but 'File' entries, since that's the only thing we care about.
        if (!line.startsWith(QLatin1String("File")))
            return true;

        QString value = getValue(line);
        if (value.isEmpty())
            return true;

        newItemFound(expandToFullPath(root, value));

        return true;
    }

    QString getValue(const QString& line) {
        int start = line.indexOf('=');
        if (start < 0)
            return QString();
        return line.midRef(start + 1).trimmed().toString();
    }
};
}

/////////////////////////////////////////////////////////////////////////////////////////////////

class QPlaylistFileParserPrivate
{
    Q_DECLARE_PUBLIC(QPlaylistFileParser)
public:
    QPlaylistFileParserPrivate(QPlaylistFileParser *q)
        : q_ptr(q)
        , m_stream(nullptr)
        , m_type(QPlaylistFileParser::UNKNOWN)
        , m_scanIndex(0)
        , m_lineIndex(-1)
        , m_utf8(false)
        , m_aborted(false)
    {
    }

    void handleData();
    void handleParserFinished();
    void abort();
    void reset();

    QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> m_source;
    QScopedPointer<ParserBase> m_currentParser;
    QByteArray      m_buffer;
    QUrl            m_root;
    QNetworkAccessManager m_mgr;
    QString m_mimeType;
    QPlaylistFileParser *q_ptr;
    QIODevice *m_stream;
    QPlaylistFileParser::FileType m_type;
    struct ParserJob
    {
        QIODevice *m_stream;
        QMediaContent m_media;
        QString m_mimeType;
        bool isValid() const { return m_stream || !m_media.isNull(); }
        void reset() { m_stream = nullptr; m_media = QMediaContent(); m_mimeType = QString(); }
    } m_pendingJob;
    int m_scanIndex;
    int m_lineIndex;
    bool m_utf8;
    bool m_aborted;

private:
    bool processLine(int startIndex, int length);
};

#define LINE_LIMIT  4096
#define READ_LIMIT  64

bool QPlaylistFileParserPrivate::processLine(int startIndex, int length)
{
    Q_Q(QPlaylistFileParser);
    m_lineIndex++;

    if (!m_currentParser) {
        const QString urlString = m_root.toString();
        const QString &suffix = !urlString.isEmpty() ? QFileInfo(urlString).suffix() : urlString;
        const QString &mimeType = m_source->header(QNetworkRequest::ContentTypeHeader).toString();
        m_type = QPlaylistFileParser::findPlaylistType(suffix, !mimeType.isEmpty() ?  mimeType : m_mimeType, m_buffer.constData(), quint32(m_buffer.size()));

        switch (m_type) {
        case QPlaylistFileParser::UNKNOWN:
            emit q->error(QPlaylistFileParser::FormatError,
                          QPlaylistFileParser::tr("%1 playlist type is unknown").arg(m_root.toString()));
            q->abort();
            return false;
        case QPlaylistFileParser::M3U:
            m_currentParser.reset(new M3UParser(q));
            break;
        case QPlaylistFileParser::M3U8:
            m_currentParser.reset(new M3UParser(q));
            m_utf8 = true;
            break;
        case QPlaylistFileParser::PLS:
            m_currentParser.reset(new PLSParser(q));
            break;
        }

        Q_ASSERT(!m_currentParser.isNull());
    }

    QString line;

    if (m_utf8) {
        line = QString::fromUtf8(m_buffer.constData() + startIndex, length).trimmed();
    } else {
        line = QString::fromLatin1(m_buffer.constData() + startIndex, length).trimmed();
    }
    if (line.isEmpty())
        return true;

    Q_ASSERT(m_currentParser);
    return m_currentParser->parseLine(m_lineIndex, line, m_root);
}

void QPlaylistFileParserPrivate::handleData()
{
    Q_Q(QPlaylistFileParser);
    while (m_source->bytesAvailable() && !m_aborted) {
        int expectedBytes = qMin(READ_LIMIT, int(qMin(m_source->bytesAvailable(),
                                                      qint64(LINE_LIMIT - m_buffer.size()))));
        m_buffer.push_back(m_source->read(expectedBytes));
        int processedBytes = 0;
        while (m_scanIndex < m_buffer.length() && !m_aborted) {
            char s = m_buffer[m_scanIndex];
            if (s == '\r' || s == '\n') {
                int l = m_scanIndex - processedBytes;
                if (l > 0) {
                    if (!processLine(processedBytes, l))
                        break;
                }
                processedBytes = m_scanIndex + 1;
                if (!m_source) {
                    //some error happened, so exit parsing
                    return;
                }
            }
            m_scanIndex++;
        }

        if (m_aborted)
            break;

        if (m_buffer.length() - processedBytes >= LINE_LIMIT) {
            emit q->error(QPlaylistFileParser::FormatError, QPlaylistFileParser::tr("invalid line in playlist file"));
            q->abort();
            break;
        }

        if (m_source->isFinished() && !m_source->bytesAvailable()) {
            //last line
            processLine(processedBytes, -1);
            break;
        }

        Q_ASSERT(m_buffer.length() == m_scanIndex);
        if (processedBytes == 0)
            continue;

        int copyLength = m_buffer.length() - processedBytes;
        if (copyLength > 0) {
            Q_ASSERT(copyLength <= READ_LIMIT);
            m_buffer = m_buffer.right(copyLength);
        } else {
            m_buffer.clear();
        }
        m_scanIndex = 0;
    }

    handleParserFinished();
}

QPlaylistFileParser::QPlaylistFileParser(QObject *parent)
    : QObject(parent)
    , d_ptr(new QPlaylistFileParserPrivate(this))
{

}

QPlaylistFileParser::~QPlaylistFileParser()
{

}

QPlaylistFileParser::FileType QPlaylistFileParser::findByMimeType(const QString &mime)
{
    if (mime == QLatin1String("text/uri-list") || mime == QLatin1String("audio/x-mpegurl") || mime == QLatin1String("audio/mpegurl"))
        return QPlaylistFileParser::M3U;

    if (mime == QLatin1String("application/x-mpegURL") || mime == QLatin1String("application/vnd.apple.mpegurl"))
        return QPlaylistFileParser::M3U8;

    if (mime == QLatin1String("audio/x-scpls"))
        return QPlaylistFileParser::PLS;

    return QPlaylistFileParser::UNKNOWN;
}

QPlaylistFileParser::FileType QPlaylistFileParser::findBySuffixType(const QString &suffix)
{
    const QString &s = suffix.toLower();

    if (s == QLatin1String("m3u"))
        return QPlaylistFileParser::M3U;

    if (s == QLatin1String("m3u8"))
        return QPlaylistFileParser::M3U8;

    if (s == QLatin1String("pls"))
        return QPlaylistFileParser::PLS;

    return QPlaylistFileParser::UNKNOWN;
}

QPlaylistFileParser::FileType QPlaylistFileParser::findByDataHeader(const char *data, quint32 size)
{
    if (!data || size == 0)
        return QPlaylistFileParser::UNKNOWN;

    if (size >= 7 && strncmp(data, "#EXTM3U", 7) == 0)
        return QPlaylistFileParser::M3U;

    if (size >= 10 && strncmp(data, "[playlist]", 10) == 0)
        return QPlaylistFileParser::PLS;

    return QPlaylistFileParser::UNKNOWN;
}

QPlaylistFileParser::FileType QPlaylistFileParser::findPlaylistType(const QString& suffix,
                                                                    const QString& mime,
                                                                    const char *data,
                                                                    quint32 size)
{

    FileType dataHeaderType = findByDataHeader(data, size);
    if (dataHeaderType != UNKNOWN)
        return dataHeaderType;

    FileType mimeType = findByMimeType(mime);
    if (mimeType != UNKNOWN)
        return mimeType;

    FileType suffixType = findBySuffixType(suffix);
    if (suffixType != UNKNOWN)
        return suffixType;

    return UNKNOWN;
}

/*
 * Delegating
 */
void QPlaylistFileParser::start(const QMediaContent &media, QIODevice *stream, const QString &mimeType)
{
    if (stream)
        start(stream, mimeType);
    else
        start(media.request(), mimeType);
}

void QPlaylistFileParser::start(QIODevice *stream, const QString &mimeType)
{
    Q_D(QPlaylistFileParser);
    const bool validStream = stream ? (stream->isOpen() && stream->isReadable()) : false;

    if (!validStream) {
        Q_EMIT error(ResourceError, tr("Invalid stream"));
        return;
    }

    if (!d->m_currentParser.isNull()) {
        abort();
        d->m_pendingJob = { stream, QUrl(), mimeType };
        return;
    }

    d->reset();
    d->m_mimeType = mimeType;
    d->m_stream = stream;
    connect(d->m_stream, SIGNAL(readyRead()), this, SLOT(_q_handleData()));
    d->handleData();
}

void QPlaylistFileParser::start(const QNetworkRequest& request, const QString &mimeType)
{
    Q_D(QPlaylistFileParser);
    const QUrl &url = request.url();

    if (url.isLocalFile() && !QFile::exists(url.toLocalFile())) {
        emit error(ResourceError, QString(tr("%1 does not exist")).arg(url.toString()));
        return;
    }

    if (!d->m_currentParser.isNull()) {
        abort();
        d->m_pendingJob = { nullptr, request, mimeType };
        return;
    }

    d->reset();
    d->m_root = url;
    d->m_mimeType = mimeType;
    d->m_source.reset(d->m_mgr.get(request));
    connect(d->m_source.data(), SIGNAL(readyRead()), this, SLOT(handleData()));
    connect(d->m_source.data(), SIGNAL(finished()), this, SLOT(handleData()));
    connect(d->m_source.data(), SIGNAL(errorOccurred(QNetworkReply::NetworkError)), this, SLOT(handleError()));

    if (url.isLocalFile())
        d->handleData();
}

void QPlaylistFileParser::abort()
{
    Q_D(QPlaylistFileParser);
    d->abort();

    if (d->m_source)
        d->m_source->disconnect();

    if (d->m_stream)
        disconnect(d->m_stream, SIGNAL(readyRead()), this, SLOT(handleData()));
}

void QPlaylistFileParser::handleData()
{
    Q_D(QPlaylistFileParser);
    d->handleData();
}

void QPlaylistFileParserPrivate::handleParserFinished()
{
    Q_Q(QPlaylistFileParser);
    const bool isParserValid = !m_currentParser.isNull();
    if (!isParserValid && !m_aborted)
        emit q->error(QPlaylistFileParser::FormatNotSupportedError, QPlaylistFileParser::tr("Empty file provided"));

    if (isParserValid && !m_aborted) {
        m_currentParser.reset();
        emit q->finished();
    }

    if (!m_aborted)
        q->abort();

    if (!m_source.isNull())
        m_source.reset();

    if (m_pendingJob.isValid())
        q->start(m_pendingJob.m_media, m_pendingJob.m_stream, m_pendingJob.m_mimeType);
}

void QPlaylistFileParserPrivate::abort()
{
    m_aborted = true;
    if (!m_currentParser.isNull())
        m_currentParser->abort();
}

void QPlaylistFileParserPrivate::reset()
{
    Q_ASSERT(m_currentParser.isNull());
    Q_ASSERT(m_source.isNull());
    m_buffer.clear();
    m_root.clear();
    m_mimeType.clear();
    m_stream = 0;
    m_type = QPlaylistFileParser::UNKNOWN;
    m_scanIndex = 0;
    m_lineIndex = -1;
    m_utf8 = false;
    m_aborted = false;
    m_pendingJob.reset();
}

void QPlaylistFileParser::handleError()
{
    Q_D(QPlaylistFileParser);
    const QString &errorString = d->m_source->errorString();
    Q_EMIT error(QPlaylistFileParser::NetworkError, errorString);
    abort();
}

QT_END_NAMESPACE
