/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples 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 "fileinfothread_p.h"
#include <qdiriterator.h>
#include <qpointer.h>
#include <qtimer.h>

#include <QDebug>


FileInfoThread::FileInfoThread(QObject *parent)
    : QThread(parent),
      abort(false),
      scanPending(false),
#if QT_CONFIG(filesystemwatcher)
      watcher(nullptr),
#endif
      sortFlags(QDir::Name),
      needUpdate(true),
      folderUpdate(false),
      sortUpdate(false),
      showFiles(true),
      showDirs(true),
      showDirsFirst(false),
      showDotAndDotDot(false),
      showHidden(false),
      showOnlyReadable(false),
      caseSensitive(true)
{
#if QT_CONFIG(filesystemwatcher)
    watcher = new QFileSystemWatcher(this);
    connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(dirChanged(QString)));
    connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT(updateFile(QString)));
#endif // filesystemwatcher
}

FileInfoThread::~FileInfoThread()
{
    QMutexLocker locker(&mutex);
    abort = true;
    condition.wakeOne();
    locker.unlock();
    wait();
}

void FileInfoThread::clear()
{
    QMutexLocker locker(&mutex);
#if QT_CONFIG(filesystemwatcher)
    watcher->removePaths(watcher->files());
    watcher->removePaths(watcher->directories());
#endif
}

void FileInfoThread::removePath(const QString &path)
{
    QMutexLocker locker(&mutex);
#if QT_CONFIG(filesystemwatcher)
    if (!path.startsWith(QLatin1Char(':')))
        watcher->removePath(path);
#else
    Q_UNUSED(path);
#endif
    currentPath.clear();
}

void FileInfoThread::setPath(const QString &path)
{
    Q_ASSERT(!path.isEmpty());

    QMutexLocker locker(&mutex);
#if QT_CONFIG(filesystemwatcher)
    if (!path.startsWith(QLatin1Char(':')))
        watcher->addPath(path);
#endif
    currentPath = path;
    needUpdate = true;
    initiateScan();
}

void FileInfoThread::setRootPath(const QString &path)
{
    Q_ASSERT(!path.isEmpty());

    QMutexLocker locker(&mutex);
    rootPath = path;
}

#if QT_CONFIG(filesystemwatcher)
void FileInfoThread::dirChanged(const QString &directoryPath)
{
    Q_UNUSED(directoryPath);
    QMutexLocker locker(&mutex);
    folderUpdate = true;
    initiateScan();
}
#endif

void FileInfoThread::setSortFlags(QDir::SortFlags flags)
{
    QMutexLocker locker(&mutex);
    sortFlags = flags;
    sortUpdate = true;
    needUpdate = true;
    initiateScan();
}

void FileInfoThread::setNameFilters(const QStringList & filters)
{
    QMutexLocker locker(&mutex);
    nameFilters = filters;
    folderUpdate = true;
    initiateScan();
}

void FileInfoThread::setShowFiles(bool show)
{
    QMutexLocker locker(&mutex);
    showFiles = show;
    folderUpdate = true;
    initiateScan();
}

void FileInfoThread::setShowDirs(bool showFolders)
{
    QMutexLocker locker(&mutex);
    showDirs = showFolders;
    folderUpdate = true;
    initiateScan();
}

void FileInfoThread::setShowDirsFirst(bool show)
{
    QMutexLocker locker(&mutex);
    showDirsFirst = show;
    folderUpdate = true;
    initiateScan();
}

void FileInfoThread::setShowDotAndDotDot(bool on)
{
    QMutexLocker locker(&mutex);
    showDotAndDotDot = on;
    folderUpdate = true;
    needUpdate = true;
    initiateScan();
}

void FileInfoThread::setShowHidden(bool on)
{
    QMutexLocker locker(&mutex);
    showHidden = on;
    folderUpdate = true;
    needUpdate = true;
    initiateScan();
}

void FileInfoThread::setShowOnlyReadable(bool on)
{
    QMutexLocker locker(&mutex);
    showOnlyReadable = on;
    folderUpdate = true;
    initiateScan();
}

void FileInfoThread::setCaseSensitive(bool on)
{
    QMutexLocker locker(&mutex);
    caseSensitive = on;
    folderUpdate = true;
    initiateScan();
}

#if QT_CONFIG(filesystemwatcher)
void FileInfoThread::updateFile(const QString &path)
{
    Q_UNUSED(path);
    QMutexLocker locker(&mutex);
    folderUpdate = true;
    initiateScan();
}
#endif

void FileInfoThread::run()
{
    forever {
        bool updateFiles = false;
        QMutexLocker locker(&mutex);
        if (abort) {
            return;
        }
        if (currentPath.isEmpty() || !needUpdate) {
            emit statusChanged(currentPath.isEmpty() ? QQuickFolderListModel::Null : QQuickFolderListModel::Ready);
            condition.wait(&mutex);
        }

        if (abort) {
            return;
        }

        if (!currentPath.isEmpty()) {
            updateFiles = true;
            emit statusChanged(QQuickFolderListModel::Loading);
        }
        if (updateFiles)
            getFileInfos(currentPath);
        locker.unlock();
    }
}

void FileInfoThread::runOnce()
{
    if (scanPending)
        return;
    scanPending = true;
    QPointer<FileInfoThread> guardedThis(this);

    auto getFileInfosAsync = [guardedThis](){
        if (!guardedThis)
            return;
        guardedThis->scanPending = false;
        if (guardedThis->currentPath.isEmpty()) {
            emit guardedThis->statusChanged(QQuickFolderListModel::Null);
            return;
        }
        emit guardedThis->statusChanged(QQuickFolderListModel::Loading);
        guardedThis->getFileInfos(guardedThis->currentPath);
        emit guardedThis->statusChanged(QQuickFolderListModel::Ready);
    };

    QTimer::singleShot(0, getFileInfosAsync);
}

void FileInfoThread::initiateScan()
{
#if QT_CONFIG(thread)
    condition.wakeAll();
#else
    runOnce();
#endif
}

void FileInfoThread::getFileInfos(const QString &path)
{
    QDir::Filters filter;
    if (caseSensitive)
        filter = QDir::CaseSensitive;
    if (showFiles)
        filter = filter | QDir::Files;
    if (showDirs)
        filter = filter | QDir::AllDirs | QDir::Drives;
    if (!showDotAndDotDot)
        filter = filter | QDir::NoDot | QDir::NoDotDot;
    else if (path == rootPath)
        filter = filter | QDir::NoDotDot;
    if (showHidden)
        filter = filter | QDir::Hidden;
    if (showOnlyReadable)
        filter = filter | QDir::Readable;
    if (showDirsFirst)
        sortFlags = sortFlags | QDir::DirsFirst;

    QDir currentDir(path, QString(), sortFlags);
    QList<FileProperty> filePropertyList;

    const QFileInfoList fileInfoList = currentDir.entryInfoList(nameFilters, filter, sortFlags);

    if (!fileInfoList.isEmpty()) {
        filePropertyList.reserve(fileInfoList.count());
        for (const QFileInfo &info : fileInfoList) {
            //qDebug() << "Adding file : " << info.fileName() << "to list ";
            filePropertyList << FileProperty(info);
        }
        if (folderUpdate) {
            int fromIndex = 0;
            int toIndex = currentFileList.size()-1;
            findChangeRange(filePropertyList, fromIndex, toIndex);
            folderUpdate = false;
            currentFileList = filePropertyList;
            //qDebug() << "emit directoryUpdated : " << fromIndex << " " << toIndex;
            emit directoryUpdated(path, filePropertyList, fromIndex, toIndex);
        } else {
            currentFileList = filePropertyList;
            if (sortUpdate) {
                emit sortFinished(filePropertyList);
                sortUpdate = false;
            } else
                emit directoryChanged(path, filePropertyList);
        }
    } else {
        // The directory is empty
        if (folderUpdate) {
            int fromIndex = 0;
            int toIndex = currentFileList.size()-1;
            folderUpdate = false;
            currentFileList.clear();
            emit directoryUpdated(path, filePropertyList, fromIndex, toIndex);
        } else {
            currentFileList.clear();
            emit directoryChanged(path, filePropertyList);
        }
    }
    needUpdate = false;
}

void FileInfoThread::findChangeRange(const QList<FileProperty> &list, int &fromIndex, int &toIndex)
{
    if (currentFileList.size() == 0) {
        fromIndex = 0;
        toIndex = list.size();
        return;
    }

    int i;
    int listSize = list.size() < currentFileList.size() ? list.size() : currentFileList.size();
    bool changeFound = false;

    for (i=0; i < listSize; i++) {
        if (list.at(i) != currentFileList.at(i)) {
            changeFound = true;
            break;
        }
    }

    if (changeFound)
        fromIndex = i;
    else
        fromIndex = i-1;

    // For now I let the rest of the list be updated..
    toIndex = list.size() > currentFileList.size() ? list.size() - 1 : currentFileList.size() - 1;
}
