#include "appserver.h"
#include "clientthread.h"
#include "../ytDMPServerDog/dogshm.h"

AppServer::AppServer(QObject *parent) : QTcpServer(parent)
{
    isWorking = false;
    UpTime = 0;
    logThread = new LogThread(this);
    AppPDataList.clear();
    db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("101.133.214.75");
    db.setPort(3306);
    db.setUserName("usky");
    db.setPassword("Yt#75Usky");
    db.setDatabaseName("usky-cloud");
    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,&AppServer::timeout);
    timeout();
}


void AppServer::start()
{
    if(listen(QHostAddress::Any,51212)){
        printf("listen 51212 start\n");
    }else{
        printf("listen failed\n");
        exit(-1);
    }
    logThread->start();
    timer->start(1000);
}

void AppServer::timeout()
{
    if(!isWorking){
        isWorking=true;
        uint t = QDateTime::currentDateTime().toTime_t();
        dogshm->version_feedtime = t;
        if((t-UpTime)>1800){
            if(db.open()){
                QList<AppPData> tmpList;
                QStringList AppIDList;
                UpTime=t;
                QSqlQuery qry;
                AppIDList.clear();
                qry = db.exec("select software_id from dmp_software_info");
                while(qry.next()){
                    AppIDList.append(qry.value(0).toString());
                }
                qry.clear();
                for(int i=0;i<AppIDList.length();i++)
                {
                    qry = db.exec(QString("SELECT software_id,id,major_version,minor_version,package_length,implement_time,check_code FROM dmp_software_upgrade where software_id='%1' order by major_version,minor_version desc limit 0,1").arg(AppIDList.at(i)));
                    if (qry.next()) {
                        AppPData pdata = AppPData(qry.value(0).toString(), qry.value(6).toString(), qry.value(2).toInt(), qry.value(3).toInt(), qry.value(4).toUInt(), qry.value(5).toDateTime().toTime_t());
                        QSqlQuery qry2 = db.exec(QString("select subpackage_number,apply_package,subpackage_length,check_code from dmp_software_subpackage where upgrade_id = %1 order by subpackage_number").arg(qry.value(1).toInt()));
                        int nrow = 0;
                        while(qry2.next()){
                            QByteArray d = qry2.value(1).toByteArray();
                            bool ok;
                            if((d.length()==qry2.value(2).toInt())&&(nrow==qry2.value(0).toInt())){
                                pdata.AppendData(PData(qry2.value(3).toString().toUInt(&ok,16)&0xffff,d));
                                nrow++;
                                printf("nrow = %d\n",nrow);
                            }else{
                                db.close();
                                isWorking=false;
                                return;
                            }
                        }
                        tmpList.append(pdata);
                    }
                }

                db.close();
                if(tmpList.length()>0){
                    AppPDataList.clear();
                    AppPDataList.append(tmpList);
                }
            }
        }
        isWorking=false;
    }
}

void AppServer::commlog(QByteArray data, bool flag){
    QString log = QString("[ %1 %2 ] ").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")).arg(flag?"<<<":">>>");
    for(int i=0;i<data.length();i++)
        log.append(QString("%1 ").arg(data.at(i)&0xff,2,16,QChar('0')));
    logThread->appendData(log);
}

void AppServer::datalog(QString log){
    QString dat = QString("[ %1 ]").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
    dat.append(log);
    logThread->appendData(dat);
}

void AppServer::incomingConnection(qintptr socketDescriptor)
{
    ClientThread *thread = new ClientThread(socketDescriptor,this);
    thread->setAppPDataList(AppPDataList);
    printf("AppPDataList0.length() [%d]\n",AppPDataList.length());
    connect(thread,&ClientThread::commlog,this,&AppServer::commlog);
    connect(thread,&ClientThread::datalog,this,&AppServer::datalog);
    connect(thread,&ClientThread::finished,thread,&ClientThread::quit);
    thread->run();
}
