/****************************************************************************
**
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins 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 "qandroidassetsfileenginehandler.h"
#include "androidjnimain.h"
#include <optional>

#include <QCoreApplication>
#include <QVector>
#include <QtCore/private/qjni_p.h>

QT_BEGIN_NAMESPACE

static const QLatin1String assetsPrefix("assets:");
const static int prefixSize = 7;

static inline QString cleanedAssetPath(QString file)
{
    if (file.startsWith(assetsPrefix))
        file.remove(0, prefixSize);
    file.replace(QLatin1String("//"), QLatin1String("/"));
    if (file.startsWith(QLatin1Char('/')))
        file.remove(0, 1);
    if (file.endsWith(QLatin1Char('/')))
        file.chop(1);
    return file;
}

static inline QString prefixedPath(QString path)
{
    path = assetsPrefix + QLatin1Char('/') + path;
    path.replace(QLatin1String("//"), QLatin1String("/"));
    return path;
}

struct AssetItem {
    enum class Type {
        File,
        Folder,
        Invalid
    };
    AssetItem() = default;
    AssetItem (const QString &rawName)
        : name(rawName)
    {
        if (name.endsWith(QLatin1Char('/'))) {
            type = Type::Folder;
            name.chop(1);
        }
    }
    Type type = Type::File;
    QString name;
};

using AssetItemList = QVector<AssetItem>;

class FolderIterator : public AssetItemList
{
public:
    static QSharedPointer<FolderIterator> fromCache(const QString &path, bool clone)
    {
        QMutexLocker lock(&m_assetsCacheMutex);
        QSharedPointer<FolderIterator> *folder = m_assetsCache.object(path);
        if (!folder) {
            folder = new QSharedPointer<FolderIterator>{new FolderIterator{path}};
            if ((*folder)->empty() || !m_assetsCache.insert(path, folder)) {
                QSharedPointer<FolderIterator> res = *folder;
                delete folder;
                return res;
            }
        }
        return clone ? QSharedPointer<FolderIterator>{new FolderIterator{*(*folder)}} : *folder;
    }

    static AssetItem::Type fileType(const QString &filePath)
    {
        const QStringList paths = filePath.split(QLatin1Char('/'));
        QString fullPath;
        AssetItem::Type res = AssetItem::Type::Invalid;
        for (const auto &path: paths) {
            auto folder = fromCache(fullPath, false);
            auto it = std::lower_bound(folder->begin(), folder->end(), AssetItem{path}, [](const AssetItem &val, const AssetItem &assetItem) {
                return val.name < assetItem.name;
            });
            if (it == folder->end() || it->name != path)
                return AssetItem::Type::Invalid;
            if (!fullPath.isEmpty())
                fullPath.append(QLatin1Char('/'));
            fullPath += path;
            res = it->type;
        }
        return res;
    }

    FolderIterator(const FolderIterator &other)
        : AssetItemList(other)
        , m_index(-1)
        , m_path(other.m_path)
    {}

    FolderIterator(const QString &path)
        : m_path(path)
    {
        QJNIObjectPrivate files = QJNIObjectPrivate::callStaticObjectMethod(QtAndroid::applicationClass(),
                                                                            "listAssetContent",
                                                                            "(Landroid/content/res/AssetManager;Ljava/lang/String;)[Ljava/lang/String;",
                                                                            QtAndroid::assets(), QJNIObjectPrivate::fromString(path).object());
        if (files.isValid()) {
            QJNIEnvironmentPrivate env;
            jobjectArray jFiles = static_cast<jobjectArray>(files.object());
            const jint nFiles = env->GetArrayLength(jFiles);
            for (int i = 0; i < nFiles; ++i) {
                AssetItem item{QJNIObjectPrivate::fromLocalRef(env->GetObjectArrayElement(jFiles, i)).toString()};
                insert(std::upper_bound(begin(), end(), item, [](const auto &a, const auto &b){
                    return a.name < b.name;
                }), item);
            }
        }
        m_path = assetsPrefix + QLatin1Char('/') + m_path + QLatin1Char('/');
        m_path.replace(QLatin1String("//"), QLatin1String("/"));
    }

    QString currentFileName() const
    {
        if (m_index < 0 || m_index >= size())
            return {};
        return at(m_index).name;
    }
    QString currentFilePath() const
    {
        if (m_index < 0 || m_index >= size())
            return {};
        return m_path + at(m_index).name;
    }

    bool hasNext() const
    {
        return !empty() && m_index + 1 < size();
    }

    std::optional<std::pair<QString, AssetItem>> next()
    {
        if (!hasNext())
            return {};
        ++m_index;
        return std::pair<QString, AssetItem>(currentFileName(), at(m_index));
    }

private:
    int m_index = -1;
    QString m_path;
    static QCache<QString, QSharedPointer<FolderIterator>> m_assetsCache;
    static QMutex m_assetsCacheMutex;
};

QCache<QString, QSharedPointer<FolderIterator>> FolderIterator::m_assetsCache(std::max(50, qEnvironmentVariableIntValue("QT_ANDROID_MAX_ASSETS_CACHE_SIZE")));
QMutex FolderIterator::m_assetsCacheMutex;

class AndroidAbstractFileEngineIterator: public QAbstractFileEngineIterator
{
public:
    AndroidAbstractFileEngineIterator(QDir::Filters filters,
                                      const QStringList &nameFilters,
                                      const QString &path)
        : QAbstractFileEngineIterator(filters, nameFilters)
    {
        m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(path), true));
        if (m_stack.last()->empty())
            m_stack.pop_back();
    }

    QFileInfo currentFileInfo() const override
    {
        return QFileInfo(currentFilePath());
    }

    QString currentFileName() const override
    {
        if (!m_currentIterator)
            return {};
        return m_currentIterator->currentFileName();
    }

    virtual QString currentFilePath() const
    {
        if (!m_currentIterator)
            return {};
        return m_currentIterator->currentFilePath();
    }

    bool hasNext() const override
    {
        if (m_stack.empty())
            return false;
        if (!m_stack.last()->hasNext()) {
            m_stack.pop_back();
            return hasNext();
        }
        return true;
    }

    QString next() override
    {
        if (m_stack.empty()) {
            m_currentIterator.reset();
            return {};
        }
        m_currentIterator = m_stack.last();
        auto res = m_currentIterator->next();
        if (!res)
            return {};
        if (res->second.type == AssetItem::Type::Folder) {
            m_stack.push_back(FolderIterator::fromCache(cleanedAssetPath(currentFilePath()), true));
            if (m_stack.last()->empty())
                m_stack.pop_back();
        }
        return res->first;
    }

private:
    mutable QSharedPointer<FolderIterator> m_currentIterator;
    mutable QVector<QSharedPointer<FolderIterator>> m_stack;
};

class AndroidAbstractFileEngine: public QAbstractFileEngine
{
public:
    explicit AndroidAbstractFileEngine(AAssetManager *assetManager, const QString &fileName)
        : m_assetManager(assetManager)
    {
        setFileName(fileName);
    }

    ~AndroidAbstractFileEngine()
    {
        close();
    }

    bool open(QIODevice::OpenMode openMode) override
    {
        if (m_isFolder || (openMode & QIODevice::WriteOnly))
            return false;
        close();
        m_assetFile = AAssetManager_open(m_assetManager, m_fileName.toUtf8(), AASSET_MODE_BUFFER);
        return m_assetFile;
    }

    bool close() override
    {
        if (m_assetFile) {
            AAsset_close(m_assetFile);
            m_assetFile = 0;
            return true;
        }
        m_isFolder = false;
        return false;
    }

    qint64 size() const override
    {
        if (m_assetFile)
            return AAsset_getLength(m_assetFile);
        return -1;
    }

    qint64 pos() const override
    {
        if (m_assetFile)
            return AAsset_seek(m_assetFile, 0, SEEK_CUR);
        return -1;
    }

    bool seek(qint64 pos) override
    {
        if (m_assetFile)
            return pos == AAsset_seek(m_assetFile, pos, SEEK_SET);
        return false;
    }

    qint64 read(char *data, qint64 maxlen) override
    {
        if (m_assetFile)
            return AAsset_read(m_assetFile, data, maxlen);
        return -1;
    }

    bool isSequential() const override
    {
        return false;
    }

    bool caseSensitive() const override
    {
        return true;
    }

    bool isRelativePath() const override
    {
        return false;
    }

    FileFlags fileFlags(FileFlags type = FileInfoAll) const override
    {
        FileFlags commonFlags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
        FileFlags flags;
        if (m_assetFile)
            flags = FileType | commonFlags;
        else if (m_isFolder)
            flags = DirectoryType | commonFlags;
        return type & flags;
    }

    QString fileName(FileName file = DefaultName) const override
    {
        int pos;
        switch (file) {
        case DefaultName:
        case AbsoluteName:
        case CanonicalName:
                return prefixedPath(m_fileName);
        case BaseName:
            if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1)
                return prefixedPath(m_fileName.mid(pos));
            else
                return prefixedPath(m_fileName);
        case PathName:
        case AbsolutePathName:
        case CanonicalPathName:
            if ((pos = m_fileName.lastIndexOf(QChar(QLatin1Char('/')))) != -1)
                return prefixedPath(m_fileName.left(pos));
            else
                return prefixedPath(m_fileName);
        default:
            return QString();
        }
    }

    void setFileName(const QString &file) override
    {
        if (m_fileName == cleanedAssetPath(file))
            return;
        close();
        m_fileName = cleanedAssetPath(file);
        switch (FolderIterator::fileType(m_fileName)) {
        case AssetItem::Type::File:
            open(QIODevice::ReadOnly);
            break;
        case AssetItem::Type::Folder:
            m_isFolder = true;
            break;
        case AssetItem::Type::Invalid:
            break;
        }
    }

    Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override
    {
        if (m_isFolder)
            return new AndroidAbstractFileEngineIterator(filters, filterNames, m_fileName);
        return nullptr;
    }

private:
    AAsset *m_assetFile = nullptr;
    AAssetManager *m_assetManager = nullptr;
    QString m_fileName;
    bool m_isFolder = false;
};


AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler()
{
    m_assetManager = QtAndroid::assetManager();
}

QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &fileName) const
{
    if (fileName.isEmpty())
        return nullptr;

    if (!fileName.startsWith(assetsPrefix))
        return nullptr;

    QString path = fileName.mid(prefixSize);
    path.replace(QLatin1String("//"), QLatin1String("/"));
    if (path.startsWith(QLatin1Char('/')))
        path.remove(0, 1);
    if (path.endsWith(QLatin1Char('/')))
        path.chop(1);
    return new AndroidAbstractFileEngine(m_assetManager, path);
}

QT_END_NAMESPACE
