#include <QFileInfo>
#include <QStringList>
#include <QDebug>
#include <QHash>
#include <QProcess>

#include "filevisitor.h"

FileVisitor::FileVisitor(QString nameFilter, bool recursive, bool symlinks) {
    m_filterList << nameFilter;
    m_Recursive = recursive;
    m_DirFilter = QDir::Files;
    if (symlinks == false) m_DirFilter = m_DirFilter | QDir::NoSymLinks;

}
FileVisitor::FileVisitor(QStringList nameFilters, bool recursive, bool symlinks) :
    m_filterList(nameFilters), m_Recursive(recursive),
    m_DirFilter(QDir::Files) {
    if (symlinks == false) m_DirFilter = m_DirFilter | QDir::NoSymLinks;
}


QStringList FileVisitor::readLines(QString filename) {
    QFile f(filename);
    return readLines(f);
}

QStringList FileVisitor::readLines(QFile &file) {
    QStringList lines;
    if ( file.open( QIODevice::ReadOnly ) ) {
        QTextStream stream( &file );
        while ( !stream.atEnd() ) {
            lines << stream.readLine(); /* line of text excluding '\n' */
        }
        file.close();
    }
    return lines;
}


static QHash<QString, QString> envToMap(QStringList envList) {
    QHash<QString, QString> retval;
    foreach (QString entry, envList) {
        QStringList kvp = entry.split("=");
        retval[kvp[0]] = kvp[1];
    }
    return retval;
}

static QString getHomeDir() {
    QHash<QString, QString> environment = envToMap(QProcess::systemEnvironment());
    return environment["HOME"];
}


QString FileVisitor::expandTilde(QString path) {
    static QString homedir = getHomeDir();
    if (path.startsWith("~")) {
        path.replace(0, 1, homedir);
    }
    return path;
}

//start id="filevisit1"
void FileVisitor::processFile(QString filename) { /* Override this method to do something more interesting with each file. */
    emit foundFile(filename);
}

void FileVisitor::processEntry(QString current) {
    current = expandTilde(current);
    QFileInfo finfo(current);
    processEntry(finfo);
}

void FileVisitor::processEntry(QFileInfo finfo) {
    //    qDebug(QString("ProcessEntry: %1").arg(finfo.fileName()));

    if (finfo.isDir()) {
        QString dirname = finfo.fileName();
        if ((dirname==".") || (dirname == ".."))
            return;
        QDir d(finfo.canonicalFilePath());
        if (skipDir(d))
            return;
        processDir(d);
    } else
        processFile(finfo.canonicalFilePath());
}
//end


void FileVisitor::processFileList(QStringList sl) {
    foreach (QString current, sl) {
        processEntry(current);
    }
}

void FileVisitor::processDir(QString pathname) {
    QDir d(pathname);
    return processDir(d);
}


bool FileVisitor::skipDir(const QDir& d) {
    bool retval = false;
    QString name = d.canonicalPath();
    if (name.contains("CVS")) {
        retval = true;
    }
    if (name == "..")
        retval=true;

    if (retval==true) {
        //qDebug(QString("  Skipdir: %1").arg(name));
    }
    return retval;
}

void FileVisitor::addNameFilter(QString nf) {
    m_filterList << nf;
}

void FileVisitor::setFilters(QStringList f) {
        m_filterList = f;
}

//start
void FileVisitor::processDir(QDir& d) {
    d.setSorting( QDir::Name );
    QStringList files = d.entryList(m_filterList, m_DirFilter);
    foreach(QString entry, files) {
        processEntry(d.filePath(entry));
    }

    if (m_Recursive) {
        QStringList dirs = d.entryList(QDir::Dirs);
        foreach (QString dir, dirs) {
            processEntry(d.filePath(dir));
        }
    }
}
//end

