/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of Qt 3D Studio.
**
** $QT_BEGIN_LICENSE:GPL$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) 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.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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QSOURCEINFO_P_H
#define QSOURCEINFO_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <private/q3dsruntimeglobal_p.h>
#include <private/qobject_p.h>
#include <QtCore/qurl.h>
#include <QtCore/qfileinfo.h>
#include <QtQml/qqmlfile.h>

#include "q3dslogging_p.h"

QT_BEGIN_NAMESPACE

class Q3DSV_PRIVATE_EXPORT Q3DSSourceInfo {
public:
    Q3DSSourceInfo()
    {
        m_variantFilter.reset(new QHash<QStringRef, QVector<QStringRef>>);
        m_internalVariantList.reset(new QVector<QString>);
    }

    ~Q3DSSourceInfo()
    {
        m_variantFilter.reset();
        m_internalVariantList.reset();
    }

    Q3DSSourceInfo(const Q3DSSourceInfo &other)
    {
        operator=(other);
    }

    inline Q3DSSourceInfo &operator=(const Q3DSSourceInfo &other)
    {
        m_url = other.m_url;
        m_fileName = other.m_fileName;
        m_variantList = other.m_variantList;
        m_internalVariantList = other.m_internalVariantList;
        m_variantFilter = other.m_variantFilter;
        return *this;
    }

    inline bool operator==(const Q3DSSourceInfo &other)
    {
        return (this->m_url == other.m_url
                && this->m_variantList == other.m_variantList);
    }

    inline bool operator!=(const Q3DSSourceInfo &other)
    {
        return (this->m_url != other.m_url
                || this->m_variantList != other.m_variantList);
    }

    inline void setUrl(const QUrl &url)
    {
        m_url = url;
        m_fileName = QQmlFile::urlToLocalFileOrQrc(url);
    }

    inline QUrl url() const { return m_url; }

    inline void setFileName(const QString &fileName)
    {
        m_fileName = fileName;
        m_url = QUrl::fromLocalFile(QFileInfo(fileName).absolutePath());
    }

    inline bool isEmpty() const { return m_url.isEmpty(); }

    inline QString fileName() const { return m_fileName; }

    inline void setVariantList(const QStringList &variantList)
    {
        //  Store the QStringList to be returned from the API
        m_variantList = variantList;

        // Note that all instances that share the filter lists will get updated
        m_variantFilter->clear();
        m_internalVariantList->clear();

        // Build a fixed (in mem location) list of the variant strings
        for (const auto &tag : variantList)
            m_internalVariantList->append(tag);

        // Parse the variantGroup:variant list to map using the fixed list
        const auto &internalList = *m_internalVariantList.data();
        for (const auto &tag : internalList) {
            QStringRef refTag = QStringRef(&tag);
            int separatorIdx = refTag.indexOf(QLatin1Char(':'));
            QStringRef group = refTag.left(separatorIdx);
            QStringRef variant = refTag.mid(separatorIdx + 1);
            (*m_variantFilter)[group].append(variant);
        }
    }

    inline const QStringList &variantList() const { return m_variantList; }
    inline const QHash<QStringRef, QVector<QStringRef>> &variantMap() const
    {
        return *m_variantFilter.data();
    }

private:
    QUrl m_url;
    QString m_fileName;
    QStringList m_variantList;
    QSharedPointer<QVector<QString>> m_internalVariantList;
    QSharedPointer<QHash<QStringRef, QVector<QStringRef>>> m_variantFilter;
};

QT_END_NAMESPACE

#endif // QSOURCEINFO_P_H
