#include <QTimer>
#include <unistd.h>
#include <QProcess>
#include "fileprocessdlg.h"
#include "ui_fileprocessdlg.h"
#include "fileprocessor.h"
#include "ovenstatics.h"
#include "stringer.h"
#include "config.h"
#include <QDebug>


#define ERROR_LOG_FILE_TOP  "/GasErrorHistoryTop.csv"
#define ERROR_LOG_FILE_STEAM  "/GasErrorHistorySteam.csv"
#define ERROR_LOG_FILE_BOTTOM  "/GasErrorHistoryBottom.csv"
#define ERROR_LOG_FILE_TOTAL    "/TotalError.csv"
#define SERVICE_DATA_FILE   "/ServiceData.csv"


ProgramCopyWorker::ProgramCopyWorker(){

}


ProgramCopyWorker::ProgramCopyWorker(QString strDest){
    m_strDestDir = strDest;
}

void ProgramCopyWorker::setDestPath(QString strDest){
    m_strDestDir = strDest;
}

void ProgramCopyWorker::workerMain(){
    quint64 nTotalFileSize=0;
    quint64 nCpyFileSize=0;
    uint16_t nCurProgress=0;
    int nRemainSec = 0;
    QStringList strdirlist;
    QString srcFilepath;
    QString destFilePath;
    bool bRst=true;

    //make destination folder
    QDir destdir(m_strDestDir);
    if(!destdir.isRoot() && destdir.exists()==false){
        destdir.mkpath(m_strDestDir);
    }
    qDebug() << "Target Path is " << m_strDestDir;


    foreach(QString strinfo, m_arrSrcFileList){
        QString filepath = strinfo.left(strinfo.indexOf(',',0));
        QFileInfo finfo(filepath);
        nTotalFileSize+= finfo.size();        
    }
    qDebug() << "File List info : count = " << m_arrSrcFileList.size() << ", File Total Size = " << nTotalFileSize;

    foreach(QString srcpath, m_arrSrcDirList){
        nTotalFileSize += FileProcessor::getDirSize(srcpath);
    }
    qDebug() << " Dir List info : count = " << m_arrSrcFileList.size() << ", File Total Size = " << nTotalFileSize;
    if(nTotalFileSize <=0 ){
        emit errorFired("SIZE ERROR ");
        QThread::currentThread()->msleep(1000);
        bRst = false;
        emit progressed(0,0);
        emit finished();
        return;
    }


    foreach(QString strinfo, m_arrSrcFileList){
        QString filepath = strinfo.left(strinfo.indexOf(',',0));
        QString destfiledir = strinfo.right(strinfo.size() - (strinfo.indexOf(',',0)+1));
        QDir destdir(destfiledir);
        if(destdir.exists() == false) destdir.mkpath(destfiledir);
        QFileInfo finfo(filepath);
        srcFilepath = filepath;
        destFilePath = QString("%1/%2").arg(destfiledir).arg(finfo.fileName());
        if(QFile::exists(destFilePath)){
            QFile::rename(destFilePath, QString("%1.bak").arg(destFilePath));
        }
        if(QFile::copy(srcFilepath,destFilePath)==false){
            qDebug() << srcFilepath << " file copy fail!";
            bRst = false;
            emit errorFired(finfo.fileName());
            QThread::currentThread()->msleep(5000);
            break;
        }
        nCpyFileSize += finfo.size();
        nCurProgress = (nCpyFileSize *100) / nTotalFileSize;
        nRemainSec = (nTotalFileSize-nCpyFileSize)/200000;
        emit progressed(nCurProgress,nRemainSec);
        if(QThread::currentThread()->isInterruptionRequested()){
            sync();
            QThread::currentThread()->quit();
            break;
        }
        QThread::currentThread()->msleep(10);
    }

    qDebug() << "File List Copy Finished";

    if(QThread::currentThread()->isInterruptionRequested() == false &&  bRst == true){
        foreach(QString srcpath, m_arrSrcDirList){
            qDebug() << "src dir : " << srcpath;

            QDir srcdir(srcpath);
            if(srcdir.exists() == false){
                qDebug() << "Source Dir is not exist";
                bRst = false;
                emit errorFired("DIR not exist");
                QThread::currentThread()->msleep(5000);
                break;
            }

            strdirlist.append(srcpath);
            FileProcessor::getAllDirList(srcdir, strdirlist);
            qDebug() << "dir size  : " <<strdirlist.size();

            QString targetpath =QString("%1%2").arg(m_strDestDir).arg(srcpath.mid(srcpath.lastIndexOf('/')));
            qDebug() << "target dir : " << targetpath;

            QDir destDir(targetpath);
            if(destDir.exists()) {
                qDebug() << "rename target path";
                QDir().rename(targetpath, QString("%1_").arg(targetpath));
            }

            foreach(QString strDir, strdirlist){
                QDir srcItem(strDir);
                srcItem.mkpath( QString(strDir).replace(srcpath,targetpath));
                QFileInfoList strFileInfolist = srcItem.entryInfoList(QDir::Files |  QDir::NoSymLinks | QDir::NoDotAndDotDot);
                foreach(QFileInfo finfo, strFileInfolist){
                    srcFilepath = finfo.absoluteFilePath();
                    destFilePath = QString("%1/%2").arg(QString(strDir).replace(srcpath,targetpath)).arg(finfo.fileName());
                    if(QFile::copy(srcFilepath, destFilePath)==false){
                        bRst = false;
                        emit errorFired(finfo.fileName());
                        qDebug() << srcFilepath << " file copy fail!";
                        QThread::currentThread()->msleep(5000);
                        break;
                    }
                    nCpyFileSize += finfo.size();
                    nCurProgress = (nCpyFileSize *100) / nTotalFileSize;
                    nRemainSec = (nTotalFileSize-nCpyFileSize)/200000;

                    //qDebug() << srcFilepath << destFilePath << "total size " << nTotalFileSize << "nCpyFileSize " << nCpyFileSize;
                    emit progressed(nCurProgress,nRemainSec);
                    if(QThread::currentThread()->isInterruptionRequested()){
                        sync();
                        break;
                    }
                    //QThread::currentThread()->msleep(100);
                }
                if(QThread::currentThread()->isInterruptionRequested() || bRst == false) break;
            }
            strdirlist.clear();
            if(QThread::currentThread()->isInterruptionRequested() || bRst==false) break;
        }
    }
    qDebug() << "File Copy Complete! SRC File Size = " << nTotalFileSize << "DEST File Size = " << nCpyFileSize;
    sync();
    if(QThread::currentThread()->isInterruptionRequested() || bRst == false){
        foreach(QString strinfo, m_arrSrcFileList){
            QString filepath = strinfo.left(strinfo.indexOf(',',0)+1);
            QString destfiledir = strinfo.right(strinfo.size() - (strinfo.indexOf(',',0)+1));
            QFileInfo finfo(filepath);
            srcFilepath = filepath;
            destFilePath = QString("%1/%2").arg(destfiledir).arg(finfo.fileName());
            if(QFile::exists( QString("%1.bak").arg(destFilePath))){
                QFile::remove(destFilePath);
                QFile::rename(QString("%1.bak").arg(destFilePath), destFilePath);
                nCpyFileSize -= finfo.size();
                nCurProgress = (nCpyFileSize *100) / nTotalFileSize;
                emit progressed(nCurProgress, nRemainSec);
            }
            QThread::currentThread()->msleep(1);
        }
        foreach(QString srcpath, m_arrSrcDirList){
            qDebug() << "src dir : " << srcpath;

            QDir srcdir(srcpath);
            QString targetpath =QString("%1%2").arg(m_strDestDir).arg(srcpath.mid(srcpath.lastIndexOf('/')));
            qDebug() << "target dir : " << targetpath;

            QDir destDir(targetpath);
            QDir renameDir(QString("%1_").arg(targetpath));
            if(renameDir.exists()) {
                qDebug() << "remove target path";
                destDir.removeRecursively();
                QDir().rename(QString("%1_").arg(targetpath), targetpath);
            }
            emit progressed(0, 0);
        }
    }
    else{
        sync();
        foreach(QString strinfo, m_arrSrcFileList){
            QString filepath = strinfo.left(strinfo.indexOf(',',0));
            QString destfiledir = strinfo.right(strinfo.size() - (strinfo.indexOf(',',0)+1));
            QDir destdir(destfiledir);
            QFileInfo finfo(filepath);
            srcFilepath = filepath;
            destFilePath = QString("%1/%2.bak").arg(destfiledir).arg(finfo.fileName());
            qDebug() << destFilePath;
            if(QFile::exists(destFilePath)){
                if(QFile(destFilePath).remove()==false){
                    qDebug() << destFilePath << "delete fail";
                }
            }
            else qDebug() << "file not found error";
        }
        foreach(QString srcpath, m_arrSrcDirList){
            qDebug() << "src dir : " << srcpath;
            QDir srcdir(srcpath);
            QString targetpath =QString("%1%2").arg(m_strDestDir).arg(srcpath.mid(srcpath.lastIndexOf('/')));
            qDebug() << "target dir : " << targetpath;
            QDir destDir(targetpath);
            QDir renameDir(QString("%1_").arg(targetpath));
            if(renameDir.exists()) {
                renameDir.removeRecursively();
            }
            emit progressed(0, 0);
        }
    }
    sync();
    emit finished();
}

void ProgramCopyWorker::addSrcDir(QString strDirPath){
    m_arrSrcDirList.append(strDirPath);
}

void ProgramCopyWorker::addSrcFile(QString strfilename){
    m_arrSrcFileList.append(strfilename);
}




void ProgramCopyWorker::haccpDownloadMain()
{
    int nDateTotalCount = m_dtStart.daysTo(m_dtEnd)+1;
    int nDateCpltCount=0;
    int year, mon, day;
    QProcess process;

    qDebug() << __func__;
    if(nDateTotalCount <= 0){
        qDebug() << "total date" << nDateTotalCount;
        emit progressed(100,0);
        emit finished();
        return;
    }

    for(QDate dt = m_dtStart; dt <= m_dtEnd; dt=dt.addDays(1)){
        year = dt.year(); mon = dt.month(); day=dt.day();
        QString path = QString("/prime/haccp/%1/%2/%3/").arg(year,2,10,QLatin1Char('4')).arg(mon, 2,10,QLatin1Char('0')).arg(day,2,10,QLatin1Char('0'));
        QDir dir(path);
        QString cmd = QString("sh -c \"zip -P primeov980308 -r %1/%2%3%4.zip *\"").arg(m_strDestDir).arg(year,2,10,QLatin1Char('4')).arg(mon, 2,10,QLatin1Char('0')).arg(day,2,10,QLatin1Char('0'));

        if(dir.exists()){
            qDebug() << "path is " << path<<  "cmd is "<< cmd;
            process.setWorkingDirectory(path);
            process.start(cmd);
            if(!process.waitForFinished(30000)){
                qDebug() << "zip failed";
            }
            process.start("sync");
            process.waitForFinished();
            nDateCpltCount++;
            emit progressed(nDateCpltCount*100/nDateTotalCount , nDateTotalCount - nDateCpltCount);
            QThread::currentThread()->msleep(300);
        }
        else {
            nDateCpltCount++;
            emit progressed( nDateCpltCount*100/nDateTotalCount , nDateTotalCount - nDateCpltCount);
            QThread::currentThread()->msleep(500);
        }
    }
    sync();
    emit finished();
}



FileProcessDlg::FileProcessDlg(QWidget *parent, ConfigType type, bool isDown) :
    QDialog(parent),
    ui(new Ui::FileProcessDlg)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_DeleteOnClose);
    setAttribute(Qt::WA_TranslucentBackground);
    setWindowFlags(Qt::FramelessWindowHint);
    qApp->setActiveWindow(this);
    this->setFocus();
    ui->ctrBtnCancel->setFocus();

    m_bRst = true;
    m_nCfgtype  = type;

    ui->ctrWjProcess->setMinimum(0);
    ui->ctrWjProcess->setMaximum(100);


    if(isDown){
        QPixmap pxmap;
        pxmap.load(":/images/config/102_usb_upload_icon.png");
        ui->label_2->setPixmap(pxmap);
    }



    switch(type){
    case config_haccp_data_download:
        QTimer::singleShot(100,this,SLOT(haccpdataDownload()));
        break;
    case config_info_data_download:
        QTimer::singleShot(100,this,SLOT(infodataDownload()));
        break;
    case config_service_data_download:
        QTimer::singleShot(100,this,SLOT(servicedataDownload()));
        break;
    case config_program_download:
        QTimer::singleShot(100,this,SLOT(programDownload()));
        break;
    case config_program_upload:
        QTimer::singleShot(100,this,SLOT(programUpload()));
        break;
    case config_set_download:
        QTimer::singleShot(100,this,SLOT(configDownload()));
        break;
    case config_set_upload:
        QTimer::singleShot(100,this,SLOT(configUpload()));
        break;
    case config_standard_info_upload:
        QTimer::singleShot(100,this,SLOT(standardInfoUpload()));
        break;
    default:
        QTimer::singleShot(200,this,SLOT(deleteLater()));
        break;
    }
}

FileProcessDlg::FileProcessDlg(QDate startdt, QDate enddt, QWidget *parent):
    QDialog(parent),
    ui(new Ui::FileProcessDlg)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_DeleteOnClose);
    setAttribute(Qt::WA_TranslucentBackground);
    setWindowFlags(Qt::FramelessWindowHint);
    qApp->setActiveWindow(this);
    this->setFocus();
    ui->ctrBtnCancel->setFocus();

    m_bRst = true;
    m_nCfgtype  = config_haccp_data_download;

    ui->ctrWjProcess->setMinimum(0);
    ui->ctrWjProcess->setMaximum(100);

    m_dtStart = startdt;
    m_dtEnd = enddt;

    QPixmap pxmap;
    pxmap.load(":/images/config/102_usb_upload_icon.png");
    ui->label_2->setPixmap(pxmap);

    QTimer::singleShot(100,this,SLOT(haccpdataDownload()));
}

FileProcessDlg::~FileProcessDlg()
{
    delete ui;
}

void FileProcessDlg::on_ctrBtnCancel_clicked()
{

    programCopyThd.requestInterruption();
    //close();
}

void FileProcessDlg::saveHistoryLineData(QTextStream &out, uint16_t i,  uint16_t fired_cnt, time_t first_fired, time_t last_fried){
    QString strLine;
    QDateTime dt;
    //for(int i =0;i<m_arrErrorMaxIdx[(uint16_t)type];i++){
   //     err_item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[type][i]]);
        strLine = tr("erro%1,").arg(i);
        if(first_fired == 0){
            strLine += "-,0,-";
        }
        else{
            dt.setTime_t(first_fired);
            strLine+= Stringer::dateTime(dt,Stringer::OneLine) + ",";
            strLine += QString("%1").arg(fired_cnt) + ",";
            dt.setTime_t(last_fried);
            strLine += Stringer::dateTime(dt,Stringer::OneLine) + ",";
        }
        out << strLine << "\n";
        qDebug() << strLine;
    //}
}

void FileProcessDlg::infodataDownload(){
    QString strUsbPath;
    QString strFile;
    QFile file;
    error_item *item;
    OvenStatistics *ovenst = OvenStatistics::getInstance();
    time_t firsttimebuf=0,lasttimebuf=0;
    uint16_t firecntbuf=0;
    uint16_t erridx = 0;
    int i;

    if(FileProcessor::detectUSB(strUsbPath)){
        //Top
        strFile = strUsbPath + ERROR_LOG_FILE_TOP;
        qDebug() << strUsbPath;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out << tr("Gas Error History\n") << "Top Ignition Box" <<"\n";
            out << tr("no,") << tr("First Appearance,") << tr("Counter,") << tr("Last Appearance\n");
            for(i =0;i<m_arrErrorMaxIdx[ERROR_HISTORY_UPPERBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_UPPERBUNNER][i]]);
                saveHistoryLineData(out,i+1,item->fired_cnt,item->first_fired,item->last_fried);
            }
            file.close();
        }
        ui->ctrWjProcess->setValue(25);
        ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1초"));
        //Bottom
        strFile = strUsbPath + ERROR_LOG_FILE_BOTTOM;
        qDebug() << strUsbPath;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out << tr("Gas Error History\n") << "Bottom Ignition Box" <<"\n";
            out << tr("no,") << tr("First Appearance,") << tr("Counter,") << tr("Last Appearance\n");
            for(i =0;i<m_arrErrorMaxIdx[ERROR_HISTORY_LOWERBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_LOWERBUNNER][i]]);
                saveHistoryLineData(out,i+1,item->fired_cnt,item->first_fired,item->last_fried);
            }
            file.close();
        }
        ui->ctrWjProcess->setValue(50);
        ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1초"));
        //Steam
        strFile = strUsbPath + ERROR_LOG_FILE_STEAM;
        qDebug() << strUsbPath;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out << tr("Gas Error History\n") << "Steam Ignition Box" <<"\n";
            out << tr("no,") << tr("First Appearance,") << tr("Counter,") << tr("Last Appearance\n");
            for(i =0;i<m_arrErrorMaxIdx[ERROR_HISTORY_STEAMBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_STEAMBUNNER][i]]);
                saveHistoryLineData(out,i+1,item->fired_cnt,item->first_fired,item->last_fried);
            }
            file.close();
        }
        ui->ctrWjProcess->setValue(75);
        ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1초"));
        //Total
        strFile = strUsbPath + ERROR_LOG_FILE_TOTAL;
        qDebug() << strUsbPath;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out << tr("Service Error History\n\n");
            out << tr("no,") << tr("First Appearance,") << tr("Counter,") << tr("Last Appearance\n");
            //01 상부 점화 장치 데이터 초기화
             firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            for(i=0;i<m_arrErrorMaxIdx[ERROR_HISTORY_UPPERBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_UPPERBUNNER][i]]);
               if(i==0) {firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;}
               else{
                    if( (firsttimebuf > item->first_fired && item->first_fired != 0) || firsttimebuf == 0 ) firsttimebuf = item->first_fired;
                    if( lasttimebuf < item->last_fried ) lasttimebuf = item->last_fried;
                    firecntbuf += item->fired_cnt;
               }
            }
            saveHistoryLineData(out,erridx+1, firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //02 스팀 점화 장치 데이터 초기화
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            for(i=0;i<m_arrErrorMaxIdx[ERROR_HISTORY_STEAMBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_STEAMBUNNER][i]]);
               if(i==0) {firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;}
               else{
                    if((firsttimebuf > item->first_fired && item->first_fired != 0) || firsttimebuf == 0 ) firsttimebuf = item->first_fired;
                    if( lasttimebuf < item->last_fried ) lasttimebuf = item->last_fried;
                    firecntbuf += item->fired_cnt;
               }
            }
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //03 하부 점화 장치 데이터 초기화
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            for(i=0;i<m_arrErrorMaxIdx[ERROR_HISTORY_LOWERBUNNER];i++){
                item = &(ovenst->srvdata->err_log.values[m_arrErrorIdxs[ERROR_HISTORY_LOWERBUNNER][i]]);
               if(i==0) {firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;}
               else{
                    if((firsttimebuf > item->first_fired && item->first_fired != 0) || firsttimebuf == 0 ) firsttimebuf = item->first_fired;
                    if( lasttimebuf < item->last_fried ) lasttimebuf = item->last_fried;
                    firecntbuf += item->fired_cnt;
               }
            }
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //04 WATER
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.inner_temp_fail);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            item = &(ovenst->srvdata->err_log.items.qunching_temp_fail);
            if( firsttimebuf > item->first_fired && item->first_fired != 0 ) firsttimebuf = item->first_fired;
            if( lasttimebuf < item->last_fried ) lasttimebuf = item->last_fried;
            firecntbuf += item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //05 구성품
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //07 B1 센서 에러
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.inner_temp_high_alarm);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //08 B2 센서 에러
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.qunching_temp_high_alarm);
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //10 B4 센서 에러
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.wall_temp1_high_alarm);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            //11 B5 센서 에러
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.steam_gen_temp_high_alram);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            firecntbuf = 0;firsttimebuf =  0; lasttimebuf=0;
            item = &(ovenst->srvdata->err_log.items.water_level_sensor_fail);
            firsttimebuf = item->first_fired;lasttimebuf = item->last_fried;firecntbuf=item->fired_cnt;
            saveHistoryLineData(out, erridx,firecntbuf,firsttimebuf,lasttimebuf);erridx++;
            file.close();
        }
        sync();
        ui->ctrWjProcess->setValue(100);
        ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 완료"));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::servicedataDownload(){
    QString strUsbPath;
    QString strHeader = "no,name,time\n";
    QString strFile;
    QFile file;
    uint32_t timetemp, totaltime=0;
    int i = 1;
    OvenStatistics *ovs = OvenStatistics::getInstance();
    if(FileProcessor::detectUSB(strUsbPath)){
        strFile = strUsbPath + SERVICE_DATA_FILE;
        file.setFileName(strFile);
        if(file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)){
            QTextStream out(&file);
            out.setCodec("UTF-8");
            out<< strHeader;
            timetemp = ovs->srvdata->use_log.items.steam_heat/3600;
            out << i++ << tr(",Steam Heating Time,") << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.dry_heat/3600;
            out << i++ << tr(",Hot Air Heating Time,") << timetemp << "h\n";

            i=1;out<< strHeader;
            timetemp = ovs->srvdata->use_log.items.cook_dry_mode/3600;
            totaltime+= ovs->srvdata->use_log.items.cook_dry_mode;
            out << i++ << tr(",Hot Air Mode,") << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.cook_steam_mode/3600;
            totaltime +=  ovs->srvdata->use_log.items.cook_steam_mode;
            out << i++ << tr(",Steam Mode,") << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.cook_combi_mode/3600;
            totaltime += ovs->srvdata->use_log.items.cook_combi_mode;
            out << i++ << tr(",Combi Mode,") << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_nocleanser/3600;
            totaltime += ovs->srvdata->use_log.items.wash_mode_nocleanser;
            out << i++ << tr(",세제없이 헹굼,").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_simple/3600;
            totaltime += ovs->srvdata->use_log.items.wash_mode_simple;
            out << i++ << tr(",간이세척,").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_standard/3600;
            totaltime += ovs->srvdata->use_log.items.wash_mode_standard;
            out << i++ << tr(",표준세척,").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_strong/3600;
            totaltime +=  ovs->srvdata->use_log.items.wash_mode_strong;
            out << i++ << tr(",강세척").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.wash_mode_speed/3600;
            totaltime +=ovs->srvdata->use_log.items.wash_mode_speed;
            out << i++ << tr(",고속세척,").toUtf8() << timetemp << "h\n";
            timetemp = ovs->srvdata->use_log.items.cooldown_mode/3600;
            totaltime += ovs->srvdata->use_log.items.cooldown_mode;
            out << i++ << tr(",쿨다운,").toUtf8() << timetemp << "h\n";
            timetemp = totaltime/3600;
            out << i++ << tr(",전체작동시간,").toUtf8() << timetemp << "h\n";

            i=1;out<< strHeader;
            timetemp = ovs->srvdata->use_log.items.door_open/60;
            out << i++ << tr(",도어 Open,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.dv_open/60;
            out << i++ << tr(",볼밸브 Open,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.ssv_open/60;
            out << i++ << tr(",S/G 급수 솔레노이드,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.qnv_open/60;
            out << i++ << tr(",퀀칭 솔레노이드,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.snv_open/60;
            out << i++ << tr(",고내살수 노즐 솔레노이드 ,").toUtf8() << timetemp << "min\n";
            timetemp = 0;
            out << i++ << tr(",호스릴 솔레노이드,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.ssp_open/60;
            out << i++ << tr(",세제공급장치,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.hdm_open/60;
            out << i++ << tr(",배습댐퍼,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.dp_open/60;
            out << i++ << tr(",소형펌프모터,").toUtf8() << timetemp << "min\n";
            timetemp = ovs->srvdata->use_log.items.unp_open/60;
            out << i++ << tr(",중형펌프모터,").toUtf8() << timetemp << "min\n";
            ui->ctrWjProcess->setValue(100);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 완료"));
            file.close();
            sync();
            QTimer::singleShot(1000,this,SLOT(close()));
        }
    }
}

void FileProcessDlg::programDownload(){
    QString strDescPath;
    QString strSrcPath;

    if(FileProcessor::detectUSB(strDescPath)){
        worker.setDestPath(QString("%1/prime").arg(strDescPath));
        worker.addSrcDir("/prime/history");
        worker.addSrcDir("/prime/program");
        worker.moveToThread(&programCopyThd);

        connect(&programCopyThd,SIGNAL(started()), &worker, SLOT(workerMain()));
        connect(&worker, SIGNAL(progressed(int,int)), this, SLOT(onProgressed(int,int)));
        connect(&worker, SIGNAL(errorFired(QString)), this, SLOT(onErrorFired(QString)));
        connect(&worker, SIGNAL(finished()), &programCopyThd,SLOT(quit()));
        connect(&programCopyThd, SIGNAL(finished()), this, SLOT(onProgressFinished()));

        programCopyThd.start();
        qDebug() << "thread start";
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::onProgressFinished(){
    QString strDescPath;
    QString strZipCmd;
    QProcess process;

    FileProcessor::detectUSB(strDescPath);

    strZipCmd = QString("sh -c \"unzip -P primeov980308 %1/prime/prime.zip -d /prime\"").arg(strDescPath);
    QFileInfo info(QString("%1/prime/prime.zip").arg(strDescPath));


    QDir cookbooksrc("/prime/cookbook");
    QDir cookBookback("/prime/cookbook_back");
    QDir multibooksrc("/prime/multi");
    QDir multibookback("/prime/multi_back");

    qDebug() << info.absoluteFilePath();

    if(m_nCfgtype == config_program_upload && info.exists()==true){
        if(cookbooksrc.exists()){
            if(cookBookback.exists()){
                process.start("sh -c \"rm -r /prime/cookbook_back\"");
                process.waitForFinished();
                process.start("sync");
                process.waitForFinished();
            }
            qDebug() << "cook book exists";
            process.start("sh -c \"mv /prime/cookbook /prime/cookbook_back\"");
            process.waitForFinished();
            process.start("sync");
            process.waitForFinished();
        }

        if(multibooksrc.exists()){
            if(multibookback.exists()){
                process.start("sh -c \"rm -r /prime/multi_back\"");
                process.waitForFinished();
                process.start("sync");
                process.waitForFinished();
            }
            qDebug() << "multi book exists";
            process.start("sh -c \"mv /prime/multi /prime/multi_back\"");
            process.waitForFinished();
            process.start("sync");
            process.waitForFinished();
        }

        qDebug() << "cook book upload";
        qDebug() << QTime::currentTime();

        process.start(strZipCmd);
        if(process.waitForFinished(120000)==false){
            ui->ctrLbRemainTime->setText("Cook book copy fail");
        }
        process.start("sync");
        process.waitForFinished();
        qDebug() << QTime::currentTime();
        if(m_bRst){
            ui->ctrLbRemainTime->setText(tr("Program & CookBook Upload Success!."));
        }else{
            ui->ctrLbRemainTime->setText(tr("CookBook Upload Success!."));
        }
        QTimer::singleShot(2000,this, SLOT(close()));
    }
    else if(m_nCfgtype == config_program_upload){
        if(m_bRst){
            ui->ctrLbRemainTime->setText(tr("Program Upload Success"));
            QTimer::singleShot(2000,this, SLOT(close()));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("Program Upload Fail"));
            QTimer::singleShot(2000,this, SLOT(close()));
        }
    }
    else{
        ui->ctrLbRemainTime->setText(tr("완료"));
        QTimer::singleShot(2000,this, SLOT(close()));
    }
}

void FileProcessDlg::onErrorFired(QString Desc)
{
    m_bRst = false;
    //ui->ctrLbRemainTime->setText(QString("%1 %2").arg(Desc).arg(tr("에러 발생으로 종료합니다.")));
    //QTimer::singleShot(1000,this, SLOT(close()));
}

void FileProcessDlg::onProgressed(int progress, int sec){
    int min, _sec;
    QString strTemp;
    qDebug() << __func__<< progress << sec;
    ui->ctrWjProcess->setValue(progress);
    min = sec/60;
    _sec = sec%60;
    if(min >0){
        strTemp = tr("남은 예상 시간 : %1분 %2초").arg(min).arg(_sec);
        ui->ctrLbRemainTime->setText(strTemp);
    }
    else{
        strTemp = QString(tr("남은 예상 시간 : %1초")).arg(_sec);
        qDebug() << strTemp;
        ui->ctrLbRemainTime->setText(strTemp);
    }
    update();
}

void FileProcessDlg::programUpload(){
    QString strDescPath;
    QString strSrcPath;




    if(FileProcessor::detectUSB(strSrcPath)){
        worker.addSrcFile(QString("%1/prime/superdaemon,/prime").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/superdaemon.ini,/prime").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/app-prime-gui,/prime").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/app-prime-modbus,/prime").arg(strSrcPath));
        //worker.addSrcFile(QString("%1/prime/service-web,/prime").arg(strSrcPath)); //Release 버전 삭제
        worker.addSrcFile(QString("%1/prime/app-prime-gui.md5,/prime").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/app-prime-modbus.md5,/prime").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/superdaemon.ini.md5,/prime").arg(strSrcPath));
        worker.addSrcFile(QString("%1/prime/superdaemon.md5,/prime").arg(strSrcPath));
        worker.setDestPath("/prime");
        //worker.addSrcDir(QString("%1/%2").arg(strSrcPath,"prime/cookbook")); //쿡북 복사 삭제
        worker.addSrcDir(QString("%1/%2").arg(strSrcPath,"prime/templates"));
        worker.addSrcDir(QString("%1/%2").arg(strSrcPath,"prime/sounds"));
        worker.moveToThread(&programCopyThd);

        connect(&programCopyThd,SIGNAL(started()), &worker, SLOT(workerMain()));
        connect(&worker, SIGNAL(progressed(int,int)), this, SLOT(onProgressed(int,int)));
        connect(&worker,SIGNAL(errorFired(QString)),this,SLOT(onErrorFired(QString)));
        connect(&worker, SIGNAL(finished()), &programCopyThd,SLOT(quit()));
        connect(&programCopyThd, SIGNAL(finished()), this, SLOT(onProgressFinished()));

        programCopyThd.start();
        qDebug() << "thread start";
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::configDownload(){
    QString strUsbPath;
    QString strSrcPath;
    if(FileProcessor::detectUSB(strUsbPath)){
        strSrcPath = QString("%1/%2").arg(strUsbPath).arg(CONFIG_FILE_NAME);
        QFileInfo finfo(strSrcPath);
        QDir fdir = finfo.absoluteDir();
        if(finfo.absoluteDir().exists() == false) fdir.mkpath(finfo.absolutePath());
        QFile file;
        file.setFileName(strSrcPath);
        if(file.exists()) file.remove();
        if(QFile::copy(CONFIG_FILE_NAME, strSrcPath)){
            sync();
            ui->ctrWjProcess->setValue(50);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1초"));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("설정 다운로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
            return;
        }
        strSrcPath = QString("%1/%2").arg(strUsbPath).arg(FAVORITE_FILE_NAME);
        file.setFileName(strSrcPath);
        if(file.exists()) file.remove();
        if(QFile::copy(FAVORITE_FILE_NAME, strSrcPath)){
            sync();
            ui->ctrWjProcess->setValue(100);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 완료"));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("즐겨찾기 다운로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::configUpload(){
    uint8_t buff[sizeof(config_lists)+1];
    qint64 readlen;
    QString strUsbPath;
    QString strSrcPath;
    Config *cfg = Config::getInstance();
    if(FileProcessor::detectUSB(strUsbPath)){
        strSrcPath = QString("%1%2").arg(strUsbPath).arg(CONFIG_FILE_NAME);
        QFile srcFile(strSrcPath);
        //Check Source File is valid this machine
        if(srcFile.open(QIODevice::ReadOnly)){
            readlen = srcFile.read((char *) buff,sizeof(config_lists)+1);
            srcFile.close();
            if(readlen != (sizeof(config_lists)+1)) {
                qDebug() << "SRC config.ini file size wrong";
                ui->ctrLbRemainTime->setText(tr("설정 업로드에 실패하였습니다."));
                QTimer::singleShot(1000,this,SLOT(close()));
                return;
            }
            if(buff[sizeof(config_lists)] != 0x9C){
                qDebug() << "SRC config.ini file check fail";
                ui->ctrLbRemainTime->setText(tr("설정 업로드에 실패하였습니다."));
                QTimer::singleShot(1000,this,SLOT(close()));
                return;
            }
            cfg->copyConfigArea((char *) buff);
            cfg->saveConfig();
            cfg->applyConfig();
        }
        else{
            qDebug() << "SRC config.ini file open fail";
            ui->ctrLbRemainTime->setText(tr("설정 업로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
            return;
        }
        strSrcPath = QString("%1/%2").arg(strUsbPath).arg(FAVORITE_FILE_NAME);
        QFile file(FAVORITE_FILE_NAME);
        file.remove();
        if(QFile::copy( strSrcPath , FAVORITE_FILE_NAME)){
            sync();
            cfg->loadFavorite();
            ui->ctrWjProcess->setValue(100);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 완료"));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("즐겨찾기 업로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::haccpdataDownload(){
    QString strSrcPath;

    if(FileProcessor::detectUSB(strSrcPath)){
        strSrcPath = QString("%1/prime/haccp").arg(strSrcPath);
        QDir dir(strSrcPath);
        if(dir.exists()){
            qDebug() << "remove dirs " << strSrcPath;
            dir.removeRecursively();
            sync();
            sleep(1);
        }
        qDebug() << "src paht is " << strSrcPath;
        dir.mkpath(strSrcPath);
        sync();
        worker.setDestPath(strSrcPath);
        worker.setStartDate(m_dtStart);
        worker.setEndDate(m_dtEnd);
        worker.moveToThread(&programCopyThd);

        connect(&programCopyThd,SIGNAL(started()), &worker, SLOT(haccpDownloadMain()));
        connect(&worker, SIGNAL(progressed(int,int)), this, SLOT(onProgressed(int,int)));
        connect(&worker,SIGNAL(errorFired(QString)),this,SLOT(onErrorFired(QString)));
        connect(&worker, SIGNAL(finished()), &programCopyThd,SLOT(quit()));
        connect(&programCopyThd, SIGNAL(finished()), this, SLOT(onProgressFinished()));

        programCopyThd.start();
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::standardInfoUpload()
{
    QString strUsbPath;
    QString strSrcPath;
    if(FileProcessor::detectUSB(strUsbPath)){
        strSrcPath = QString("%1%2").arg(strUsbPath).arg(MODEL_INFO_FILE_NAME);
        qDebug() <<strSrcPath;
        QFile file(MODEL_INFO_FILE_NAME);
        file.remove();
        sync();
        if(QFile::copy( strSrcPath ,MODEL_INFO_FILE_NAME)){
            sync();
            ui->ctrWjProcess->setValue(40);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 2초"));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("모델 정보 업로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
            return;
        }
        //QThread::msleep(800);
        file.setFileName(CHEF_INFO_FILE_NAME);
        file.remove();
        sync();
        QThread::msleep(1000);
        Config::getInstance()->loadProductInfo();
        strSrcPath = QString("%1%2").arg(strUsbPath).arg(CHEF_INFO_FILE_NAME);
        qDebug() << strSrcPath;
        if(QFile::copy( strSrcPath ,CHEF_INFO_FILE_NAME)){
            sync();
            ui->ctrWjProcess->setValue(70);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 1"));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("핫라인 쉐프 정보 업로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
        //QThread::msleep(800);
        file.setFileName(SERVICE_INFO_FILE_NAME);
        file.remove();
        sync();
        strSrcPath = QString("%1%2").arg(strUsbPath).arg(SERVICE_INFO_FILE_NAME);
        qDebug() << strSrcPath;
        if(QFile::copy( strSrcPath ,SERVICE_INFO_FILE_NAME)){
            sync();
            ui->ctrWjProcess->setValue(100);
            ui->ctrLbRemainTime->setText(tr("남은 예상 시간 : 완료"));
            qDebug() << "standard upload success";
            QTimer::singleShot(1000,this,SLOT(close()));
        }
        else{
            ui->ctrLbRemainTime->setText(tr("핫라인 서비스 정보 업로드에 실패하였습니다."));
            QTimer::singleShot(1000,this,SLOT(close()));
        }
    }
    else{
        ui->ctrLbRemainTime->setText(tr("USB 인식을 실패하였습니다."));
        QTimer::singleShot(1000,this,SLOT(close()));
    }
}

void FileProcessDlg::keyPressEvent(QKeyEvent */*event*/){

}

void FileProcessDlg::keyReleaseEvent(QKeyEvent *event){
    switch (event->key())
    {
    case 0x01000031:    // Push
    {
        QPushButton *btn = qobject_cast<QPushButton*>(focusWidget());
        if(btn != NULL){
            btn->click();
        }
        break;
    }
    }
}