#include "launcher.h"
#include "ui_launcher.h"

#include "logproc.h"
#include "CSqlite3DBProc.h"
#include "CAppInfo.h"
#include "CHttpBll.h"
#include "envCheck.h"
#include "envResult.h"
#include "upgrade.h"
#include "popMsgBox.h"
#include "CCommonTools.h"

#include <QDesktopWidget>
#include <QFile>
#include <QSettings>
#include <QFileInfo>
#include <QProcess>

#include "CWindowsFireWall.h"
#include <process.h>


launcher::launcher(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::launcher)
{
    ui->setupUi(this);

    setWindowFlags(Qt::FramelessWindowHint);

    initParam();

    CWindowsFireWall wfw(_getpid(), false);
    wfw.removeLastRules();

    QDesktopWidget *dekwiget = QApplication::desktop();
    int nWidth = dekwiget->width();
    int nHeight = dekwiget->height();
    double fWRate = (double)nWidth/1280;
    double fHRate= (double)nHeight/800;
    double fRate = fWRate;
    if(fHRate < fWRate)
    {
        fRate = fHRate;
    }

    g_appInfoPtr->m_fRate = fRate;

    QFile qssFile(":/launcher.qss");
    qssFile.open(QFile::ReadOnly);
    QString qss;
    qss = qssFile.readAll();
    int FONT_BASE_SIZE6 = 6*fRate;
    int FONT_BASE_SIZE12 = 12*fRate;
    int FONT_BASE_SIZE14 = 14*fRate;
    int FONT_BASE_SIZE16 = 16*fRate;
    int FONT_BASE_SIZE18 = 18*fRate;
    int FONT_BASE_SIZE20 = 20*fRate;
    int FONT_BASE_SIZE22 = 22*fRate;
    qss.replace("FONT_BASE_SIZE12", QString::number(FONT_BASE_SIZE12));
    qss.replace("FONT_BASE_SIZE14", QString::number(FONT_BASE_SIZE14));
    qss.replace("FONT_BASE_SIZE16", QString::number(FONT_BASE_SIZE16));
    qss.replace("FONT_BASE_SIZE18", QString::number(FONT_BASE_SIZE18));
    qss.replace("FONT_BASE_SIZE20", QString::number(FONT_BASE_SIZE20));
    qss.replace("FONT_BASE_SIZE22", QString::number(FONT_BASE_SIZE22));
    qss.replace("FONT_BASE_SIZE6", QString::number(FONT_BASE_SIZE6));
    g_appInfoPtr->m_sQssStr = qss;
    setStyleSheet(qss);

    initUI();

    QProcess process;
    process.start("systeminfo");
    process.waitForFinished();
    QByteArray qbt = process.readAllStandardOutput();
    QString sInfo = QString::fromLocal8Bit(qbt.data());
    myServerLog()<<sInfo;
}

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

void launcher::initParam()
{
//    g_appInfoPtr = std::make_shared<CAppInfo>();

    g_sysDBProcPtr = std::make_shared<CSqlite3DBProc>();
    if(!g_sysDBProcPtr->OpenDB("data/sys.db"))
    {
//        ShowMsg(QString::fromLocal8Bit("打开数据库失败！"), this);
        myDebug()<<QString::fromLocal8Bit("打开数据库失败！");
    }

    sqlite3_stmt *stmt;
    QString sSql = QString("select name,ifnull(value,'') from t_param");
    if(!g_sysDBProcPtr->QuerySql(sSql.toStdString(), &stmt))
    {
//        ShowMsg(QString::fromLocal8Bit("查询参数信息失败！"), this);
        myDebug()<<QString::fromLocal8Bit("查询参数信息失败！");
        return;
    }

    QString sProjectName = "";
    QString sEndpoint = "";
    QString sLogstore = "";
    QString sHttpServer ="";
    QString sHttpPort = "";
    QString sWebsocketServer = "";
    QString sWebsocketPort = "";
    QString sUseHttps = "";
    int nField64 = 0;
    std::string sField = "";
    g_sysDBProcPtr->BeginGetFields(stmt);
    while(!g_sysDBProcPtr->Eof())
    {
        QString sName = g_sysDBProcPtr->GetFields(0, sField, stmt).c_str();
        QString sValue = g_sysDBProcPtr->GetFields(1, sField, stmt).c_str();
        if(sName == "log_project_name")
        {
           sProjectName = sValue;
        }
        else if(sName == "log_endpoint")
        {
            sEndpoint = sValue;
        }
        else if(sName == "log_store")
        {
            sLogstore = sValue;
        }
        else if(sName == "http_server")
        {
            sHttpServer = sValue;
            QStringList sVl = sValue.split(".");
            if (sVl.count() > 0)
            {
                g_appInfoPtr->m_sOrgPrefix = sVl[0];
            }
        }
        else if(sName == "httpPort")
        {
            sHttpPort = sValue;
        }
        else if(sName == "websocketServer")
        {
            sWebsocketServer = sValue;
        }
        else if(sName == "websocketPort")
        {
            sWebsocketPort = sValue;
        }
        else if(sName == "useHttps")
        {
            sUseHttps = sValue;
        }
        else if (sName == "esc_domain")
        {
            g_appInfoPtr->m_sEscDomain = sValue;
        }

        g_sysDBProcPtr->Next(stmt);
    }
    g_sysDBProcPtr->EndGetFields(stmt);

    sSql = QString("select version_id,version_code,ifnull(machine_id,''),ifnull(update_time,'') from t_sysinfo");
    if (!g_sysDBProcPtr->QuerySql(sSql.toStdString(), &stmt))
    {
        popMsg(QString::fromLocal8Bit("加载参数信息失败！"), QString::fromLocal8Bit("系统提示"), this);
        //        myDebug()<<QString::fromLocal8Bit("查询参数信息失败！");
        return;
    }
    int nField = 0;
    g_sysDBProcPtr->BeginGetFields(stmt);
    if (!g_sysDBProcPtr->Eof())
    {
        g_appInfoPtr->m_nVersionId = g_sysDBProcPtr->GetFields(0, nField, stmt);
        g_appInfoPtr->m_sVersionCode = g_sysDBProcPtr->GetFields(1, sField, stmt).c_str();
        g_appInfoPtr->m_sMachineId = g_sysDBProcPtr->GetFields(2, sField, stmt).c_str();
    }
    g_sysDBProcPtr->EndGetFields(stmt);

    if(sProjectName.isEmpty() || sEndpoint.isEmpty() || sLogstore.isEmpty())
    {
        //未配置日志参数
    }
    else
    {
        g_logPtr = std::make_shared<CLogTrack>(sProjectName, sEndpoint, sLogstore);
    }

    g_httpBllPtr = std::make_shared<CHttpBll>();
    if(sUseHttps == "1")
    {
        g_httpBllPtr->init(sHttpServer, sHttpPort, true);
    }
    else
    {
        g_httpBllPtr->init(sHttpServer, sHttpPort);
    }

    if (g_appInfoPtr->m_sMachineId == "")
    {
        if (CCommonTools::IsWow64())
        {
            QSettings settings(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography)", QSettings::Registry64Format);
            g_appInfoPtr->m_sMachineId = settings.value("MachineGuid", "").toString();
        }
        else
        {
            QSettings settings(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography)", QSettings::Registry32Format);
            g_appInfoPtr->m_sMachineId = settings.value("MachineGuid", "").toString();
        }

        if (g_appInfoPtr->m_sMachineId == "")
        {
            g_appInfoPtr->m_sMachineId = CCommonTools::getUuid();
        }

        sSql = QString("update t_sysinfo set machine_id = '%1'").arg(g_appInfoPtr->m_sMachineId);
        if (!g_sysDBProcPtr->ExcuteSql(sSql.toStdString()))
        {
            popMsg(QString::fromLocal8Bit("保存机器信息失败！"), QString::fromLocal8Bit("系统提示"), this);
            //myDebug() << QString::fromLocal8Bit("保存机器信息失败！");
            return;
        }
    }

}

void launcher::showEvent(QShowEvent *event)
{

}


void launcher::on_btn_close_clicked()
{
    close();
}

void launcher::initUI()
{
//    initEnvInfo();

    QDesktopWidget *dekwiget = QApplication::desktop();
    setGeometry((dekwiget->width() - g_appInfoPtr->m_fRate*600)/2,
                (dekwiget->height() - g_appInfoPtr->m_fRate*340)/2,
                g_appInfoPtr->m_fRate*600, g_appInfoPtr->m_fRate*340);
    ui->launcher_bg->setGeometry(0, 0, width(), height());
    ui->btn_close->setGeometry(width() - g_appInfoPtr->m_fRate*24, 0, g_appInfoPtr->m_fRate*24, g_appInfoPtr->m_fRate*24);
    ui->sw_client->setGeometry(0, 0, width() - g_appInfoPtr->m_fRate*24, height());

    envCheck *ec = new envCheck;
    connect(ec, &envCheck::checkUnpass, this, &launcher::onCheckUnpass);
    connect(ec, &envCheck::checkpassed, this, &launcher::onCheckpassed);
    connect(ec, &envCheck::sysUpadte, this, &launcher::onSysUpadte);
    ui->sw_client->addWidget(ec);

    envResult *er = new envResult;
    ui->sw_client->addWidget(er);

    upgrade *ug = new upgrade;
    connect(ug, &upgrade::updateSucceed, this, &launcher::onUpdateSucceed);
    connect(ug, &upgrade::exitUpgrade, this, [&](){
        close();
    });
    ui->sw_client->addWidget(ug);

    ui->sw_client->setCurrentIndex(0);
    ec->startCheck();
}


void launcher::onUpdateSucceed(bool bUpdateOeLauncher)
{
    QFileInfo file("client.exe");
    QStringList sParam;
    if(bUpdateOeLauncher)
    {
        sParam<<"updateLauncher";
    }
    else
    {
        sParam<<"runClient";
    }

    QProcess::startDetached(file.absoluteFilePath(), sParam);

    close();
}

void launcher::onCheckUnpass()
{
    envCheck *ev = dynamic_cast<envCheck*>(ui->sw_client->widget(0));
    if(ev)
    {
        QStringList list = ev->unpassList();

        envResult *er = dynamic_cast<envResult*>(ui->sw_client->widget(1));
        if(er)
        {
            for(QString unpassStr : list)
            {
                er->addItem(unpassStr);
            }
            ui->sw_client->setCurrentIndex(1);
        }
    }
}

void launcher::onCheckpassed(bool bUpdateVersion)
{
    QList<UpdateInfo> sList;


    if(bUpdateVersion)
    {
        UpdateInfo upInfo;
        upInfo.nType = 2;
        upInfo.sUrl = g_appInfoPtr->m_sUpgradeUrl;
        sList.push_back(upInfo);
    }

    if(sList.count() > 0)
    {
        ui->sw_client->setCurrentIndex(2);
        upgrade *up = dynamic_cast<upgrade*>(ui->sw_client->widget(2));
        if(up)
        {
            up->startUpgrade(sList);
        }
    }
    else
    {
        QFileInfo file("client.exe");
        QStringList sParam;
        sParam<<"runClient";
        QProcess::startDetached(file.absoluteFilePath(), sParam);

        close();
    }
}

void launcher::onSysUpadte()
{
    close();
}
