#include "filesystemwatcher.h"
#include "ui_filesystemwatcher.h"

FileSystemWatcher::FileSystemWatcher(QString dirPath, QWidget *parent) :
    QMainWindow(parent),
    m_ui(new Ui::FileSystemWatcher),
    m_watcher(new QFileSystemWatcher()),
    m_listViewModel(new QStringListModel()),
    m_listView(new QListView()),
    m_timer(new QTimer(this)),
    m_dirPath(dirPath)
{
    // setup user interface
    m_ui->setupUi(this);

    // add main directory to monitor
    m_watcher->addPath(m_dirPath);

    // create the view
    m_listView->setModel(m_listViewModel);
    setCentralWidget(m_listView);

    // set title
    setWindowTitle("ChronoShare");

    // register signals (callback functions)
    connect(m_watcher, SIGNAL(directoryChanged(QString)), this, SLOT(handleCallback()));
    connect(m_timer, SIGNAL(timeout()), this, SLOT(handleCallback()));

    // bootstrap
    handleCallback();

    // start timer
    m_timer->start(10000);
}

FileSystemWatcher::~FileSystemWatcher()
{
    // clean up
    delete m_ui;
    delete m_watcher;
    delete m_listViewModel;
    delete m_listView;
    delete m_timer;
}

void FileSystemWatcher::handleCallback()
{
    // scan directory and populate file list
    QHash<QString, sFileInfo> currentState = scanDirectory(m_dirPath);

    // reconcile directory and report changes
    QVector<sEventInfo> dirChanges = reconcileDirectory(currentState);

    // update gui with list of changes in this directory
    qDebug() << endl << m_watcher->directories() << endl;

    // DEBUG: Print to Gui
    if(!dirChanges.isEmpty())
    {
        QStringList dirChangesList;

        for(int i = 0; i < dirChanges.size(); i++)
        {
            QString tempString;

            eEvent event = dirChanges[i].event;
            QString absFilePath = dirChanges[i].absFilePath;

            switch(event)
            {
            case ADDED:
                tempString.append("ADDED: ");
                break;
            case MODIFIED:
                tempString.append("MODIFIED: ");
                break;
            case DELETED:
                tempString.append("DELETED: ");
                break;
            }

            tempString.append(absFilePath);

            dirChangesList.append(tempString);
        }

        m_listViewModel->setStringList(dirChangesList);
    }
}

QHash<QString, sFileInfo> FileSystemWatcher::scanDirectory(QString dirPath)
{   
    // list of files in directory
    QHash<QString, sFileInfo> currentState;

    // directory iterator (recursive)
    QDirIterator dirIterator(dirPath, QDirIterator::Subdirectories |
                                        QDirIterator::FollowSymlinks);

    // iterate through directory recursively
    while(dirIterator.hasNext())
    {
        // Get Next File/Dir
        dirIterator.next();

        // Get FileInfo
        QFileInfo fileInfo = dirIterator.fileInfo();

        // if not this directory or previous directory
        if(fileInfo.absoluteFilePath() != ".." && fileInfo.absoluteFilePath() != ".")
        {
            QString absFilePath = fileInfo.absoluteFilePath();

            // if this is a directory
            if(fileInfo.isDir())
            {
                QStringList dirList = m_watcher->directories();

                // if the directory is not already being watched
                if (absFilePath.startsWith(m_dirPath) && !dirList.contains(absFilePath))
                {
                    // add this directory to the watch list
                    m_watcher->addPath(absFilePath);
                }
            }
            else
            {
                // construct struct
                sFileInfo fileInfoStruct;
                fileInfoStruct.fileInfo = fileInfo;

                // initialize checksum
                QCryptographicHash crypto(QCryptographicHash::Md5);

                // open file
                QFile file(fileInfo.absoluteFilePath());
                file.open(QFile::ReadOnly);

                // calculate checksum
                while(!file.atEnd())
                {
                    crypto.addData(file.read(8192));
                }

                fileInfoStruct.hash = crypto.result();

                // add this file to the file list
                currentState.insert(absFilePath, fileInfoStruct);
            }
        }
    }

    return currentState;
}

QVector<sEventInfo> FileSystemWatcher::reconcileDirectory(QHash<QString, sFileInfo> currentState)
{
    // list of files changed
    QVector<sEventInfo> dirChanges;

    // compare result (database/stored snapshot) to fileList (current snapshot)
    QMutableHashIterator<QString, sFileInfo> i(m_storedState);

    while(i.hasNext())
    {
        i.next();

        QString absFilePath = i.key();

        sFileInfo storedFileInfoStruct = i.value();
        QFileInfo storedFileInfo = storedFileInfoStruct.fileInfo;
        QByteArray storedHash = storedFileInfoStruct.hash;

        // check file existence
        if(currentState.contains(absFilePath))
        {
            sFileInfo currentFileInfoStruct = currentState.value(absFilePath);
            QFileInfo currentFileInfo = currentFileInfoStruct.fileInfo;
            QByteArray currentHash = currentFileInfoStruct.hash;

            if((storedFileInfo != currentFileInfo) || (storedHash != currentHash))
            {
                // update stored state
                i.setValue(currentFileInfoStruct);

                // this file has been modified
                sEventInfo eventInfo;
                eventInfo.event = MODIFIED;
                eventInfo.absFilePath = absFilePath;
                dirChanges.push_back(eventInfo);
            }

            // delete this file from fileList we have processed it
            currentState.remove(absFilePath);
        }
        else
        {
            // delete from stored state
            i.remove();

            // this file has been deleted
            sEventInfo eventInfo;
            eventInfo.event = DELETED;
            eventInfo.absFilePath = absFilePath;
            dirChanges.push_back(eventInfo);
        }
    }

    // any files left in fileList have been added
    for(QHash<QString, sFileInfo>::iterator i = currentState.begin(); i != currentState.end(); ++i)
    {
        QString absFilePath = i.key();
        sFileInfo currentFileInfoStruct = i.value();

        m_storedState.insert(absFilePath, currentFileInfoStruct);

        // this file has been added
        sEventInfo eventInfo;
        eventInfo.event = ADDED;
        eventInfo.absFilePath = absFilePath;
        dirChanges.push_back(eventInfo);
    }

    return dirChanges;
}

#if WAF
#include "filesystemwatcher.moc"
#include "filesystemwatcher.cpp.moc"
#endif
