/***************************** LICENSE START ***********************************

 Copyright 2017 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "MvQProgressManager.h"

#include "MvQProgressBarPanel.h"

#include <unistd.h>

//#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QFileSystemWatcher>

MvQProgressManager::MvQProgressManager(int ntotalframes, MvQProgressBarPanel* pbp, QWidget* parent) :
    QWidget(parent),
    progressBarPanel_(pbp),
    ntotalframes_(ntotalframes),
    nframes_(0)
{
    // Create a watcher
    // The paths/directories to be watched must be set by the application
    watcher_ = new QFileSystemWatcher(this);

    connect(watcher_, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged(const QString&)));

    connect(watcher_, SIGNAL(directoryChanged(const QString&)), this, SLOT(directoryChanged(const QString&)));

    // Initialise progress bar if it is available
    if (progressBarPanel_) {
        progressBarPanel_->setRange(0, ntotalframes_);
        progressBarPanel_->setValue(0);
    }
}

MvQProgressManager::~MvQProgressManager()
{
    if (watcher_) {
        delete watcher_;
        watcher_ = nullptr;
    }
}

void MvQProgressManager::directoryChanged(const QString& /*str*/)
{
    nframes_++;

    // Update progress bar if it is available
    if (progressBarPanel_)
        progressBarPanel_->setValue(nframes_);

    // All temporary files have been generated
    if (nframes_ == ntotalframes_) {
        // Last file was opened for writing. Before sending a signal,
        // it needs to wait until the file has been fully generated
        this->waitFileCreation();

        emit endTempFilesCreation();
    }
}

void MvQProgressManager::fileChanged(const QString& /*str*/)
{
    emit endFileCreation();
}

void MvQProgressManager::setVisible(bool flag)
{
    if (progressBarPanel_)
        progressBarPanel_->setVisible(flag);
}

void MvQProgressManager::waitFileCreation()
{
    // Get the first "watched" directory
    QStringList ldir = watcher_->directories();
    QDir dir(ldir.at(0).toLocal8Bit().constData());

    // Get the most recent file
    QFileInfoList list = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs, QDir::Time);
    QString fileName   = list.first().absoluteFilePath();

    // Wait until filesize has not been changed for 1 second
    int size1 = 0;
    int size2 = 0;
    while (true) {
        if (size1 == size2 && size2 != 0) {
            sleep(1);
            QFileInfo finfo(fileName);
            size2 = finfo.size();
            //qDebug() << "Slept 1 second" << size1 << size2;
            if (size1 == size2)
                break;
        }

        // Sleeps faster
        usleep(500);
        size1 = size2;
        QFileInfo finfo(fileName);
        size2 = finfo.size();
        //qDebug() << "Slept 500miliseconds" << size1 << size2;
    }
}
