#include "envCheck.h"
#include "ui_envCheck.h"

#include "CAppInfo.h"
#include "CCommonTools.h"
#include "logproc.h"
#include "popMsgBox.h"
#include <QDateTime>

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

    setStyleSheet(g_appInfoPtr->m_sQssStr);

    m_MonitorEnumeratorPtr = std::make_shared<CMultiMonitorEnumerator>();

    initUI();

    m_sCameraList<<"17GuaGua Cam"
      <<"91KBOX"
      <<"e2eSoft iVCam"
      <<"e2eSoft VCam"
      <<"FaceRig Virtual Camera"
      <<"MagicCamera Capture"
      <<"MeiSe"
      <<"Virtual Cam"
      << QString::fromLocal8Bit("YY伴侣")
      <<"WebcamMax Capture"
      <<"Wecam"
      <<"Vcam "
      <<"softcam"
      <<"Vandate Virtual Camera"
      <<"video2webcam"
      <<"VCDCut Pro"
      << QString::fromLocal8Bit("9158虚拟视频")
      <<"9158Capture"
      << "Insta360 Virtual Camera"
      << QString::fromLocal8Bit("无他直播伴侣PC客户端")
      << QString::fromLocal8Bit("无他相机电脑版")
      <<"mobiola webcamera"
      << QString::fromLocal8Bit("艾米秀宝(ImiShowBox)")
      <<"video2Webcam"
      << QString::fromLocal8Bit("飞翔虚拟视频")
      << QString::fromLocal8Bit("魔力秀")
      << QString::fromLocal8Bit("YY开播")
      << QString::fromLocal8Bit("无他伴侣")
      << QString::fromLocal8Bit("视频连麦")
      << QString::fromLocal8Bit("酷狗直播伴侣")
      <<"screen-capture-recorder"
      <<"OBS Virtual Camera"
      <<"OBS-Camera"
      <<"ManyCam Virtual Webcam"
      << QString::fromLocal8Bit("小葫芦直播助手")
      <<"yyplayer"
      << QString::fromLocal8Bit("秀色直播伴侣")
      << QString::fromLocal8Bit("秀色直播助手")
      <<"Citrix HDX Web Camera";

    m_sRemoteList
        <<"teamviewer"
        <<"lookmypc"
  //      <<"xt"
        <<"winaw32"
        <<"pcaquickconnect"
        <<"sessioncontroller"
        <<"sunlogin";
        //<<"sunloginremote";
    //		<< "qq"
//        <<"wechat"
//        <<"wemeetapp";

    m_sRemoteTipList
        <<"TeamViewer"
        <<"LookMyPC"
  //      << QString::fromLocal8Bit("协通")
        <<"Symantec PCAnywhere"
        <<"Symantec PCAnywhere"
        <<"Symantec PCAnywhere"
        << QString::fromLocal8Bit("向日葵");
     //   << QString::fromLocal8Bit("向日葵");
    //        <<"QQ"
//        << QString::fromLocal8Bit("微信")
//        << QString::fromLocal8Bit("腾讯会议");

    qRegisterMetaType<CSysNotice>("CSysNotice");
    connect(g_httpBllPtr.get(), &CHttpBll::sgnSysNotice, this, &envCheck::onSysNotice);
    qRegisterMetaType<CUpgrade>("CUpgrade");
    connect(g_httpBllPtr.get(), &CHttpBll::sgnUpgrade, this, &envCheck::onUpgrade);
    qRegisterMetaType<CStudentClientConfig>("CStudentClientConfig");
    connect(g_httpBllPtr.get(), &CHttpBll::sgnStudentClientConfig, this, &envCheck::onStudentClientConfig);
    qRegisterMetaType<CGetSoftwareConfig>("CGetSoftwareConfig");
    connect(g_httpBllPtr.get(), &CHttpBll::sgnGetSoftwareConfig, this, &envCheck::onGetSoftwareConfig);


}

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

void envCheck::onStudentClientConfig(CStudentClientConfig studentClientConfig)
{
    if (studentClientConfig.nCode == 200)
    {
        g_appInfoPtr->m_bDisableRemoteAssistance = studentClientConfig.bDisableRemoteAssistance;

        g_appInfoPtr->m_bDisableVirtualCamera = studentClientConfig.bDisableVirtualCamera;
        m_bDisableVirtualMachine = studentClientConfig.bDisableVirtualMachine;
    }
    else
    {
        popMsg(QString::fromLocal8Bit("网络异常，请检查网络连接！"), QString::fromLocal8Bit("系统提示"), this);
        return;
    }



    if(g_appInfoPtr->m_bDisableRemoteAssistance || g_appInfoPtr->m_bDisableVirtualCamera)
    {
        CHttpRequestPackage hrp;
        hrp.sUri = QString("https://%1/oe_client/software.json").arg(g_appInfoPtr->m_sEscDomain);
        hrp.nRequestType = RequestType::rtGetSoftwareConfig;
        g_httpBllPtr->getUrl(hrp);
    }
    else
    {
        checkProc();
    }
}

void envCheck::onGetSoftwareConfig(CGetSoftwareConfig getSoftwareConfig)
{
    if (getSoftwareConfig.nCode == 200)
    {
        qDebug()<<getSoftwareConfig.sSoftwareConfig.toLocal8Bit();
        QString sSoftwareConfig = QByteArray::fromBase64(getSoftwareConfig.sSoftwareConfig.toLocal8Bit());
        if(!sSoftwareConfig.isEmpty())
        {
            Json::Reader reader;
            Json::Value jsonRoot = Json::Value::null;
            if (reader.parse(sSoftwareConfig.toStdString(), jsonRoot))
            {
                QString sCamera = jsonRoot["vCamList"].asString().c_str();
                QStringList cameraList = sCamera.split("\n", QString::SkipEmptyParts);
                QString sRemoteApp = jsonRoot["remoteApp"].asString().c_str();
                QStringList remoteAppList = sRemoteApp.split("\n", QString::SkipEmptyParts);

                m_sCameraList += cameraList;

                for(QString remoteApp : remoteAppList)
                {
                    QString remoteAppProcess = remoteApp.left(remoteApp.indexOf("@@@"));
                    QString remoteAppName = remoteApp.right(remoteApp.length() - remoteApp.indexOf("@@@") - 3);
                    m_sRemoteList<<remoteAppProcess;
                    m_sRemoteTipList<<remoteAppName;
                }
//                m_sRemoteList += remoteAppList;
//                m_sRemoteTipList += remoteAppList;
           }
        }
    }

    checkProc();
}

void envCheck::initUI()
{
    setGeometry(0, 0, g_appInfoPtr->m_fRate*(600 - 24), g_appInfoPtr->m_fRate*340);
    ui->label_platformIcon->setGeometry(g_appInfoPtr->m_fRate*60, g_appInfoPtr->m_fRate*40,
                                        g_appInfoPtr->m_fRate*32, g_appInfoPtr->m_fRate*32);
    ui->label_platformTitle->adjustSize();
    ui->label_platformTitle->setGeometry(ui->label_platformIcon->x() + ui->label_platformIcon->width() + g_appInfoPtr->m_fRate*10,
                                         ui->label_platformIcon->y() + (ui->label_platformIcon->height() - ui->label_platformTitle->height())/2,
                                         ui->label_platformTitle->width(), ui->label_platformTitle->height());
    ui->label_mainHint->adjustSize();
    ui->label_mainHint->setGeometry(g_appInfoPtr->m_fRate*60, g_appInfoPtr->m_fRate*144, ui->label_mainHint->width(), ui->label_mainHint->height());
    ui->label_checkItem->adjustSize();
    ui->label_checkItem->setGeometry(ui->label_mainHint->x(), ui->label_mainHint->y() + ui->label_mainHint->height() + g_appInfoPtr->m_fRate*10,
                                     width(), ui->label_checkItem->height());
    if(!g_appInfoPtr->m_sVersionCode.isEmpty())
    {
        ui->label_version->setText(QString("V%1").arg(g_appInfoPtr->m_sVersionCode));
    }
    ui->label_version->adjustSize();
    ui->label_version->setGeometry(ui->label_mainHint->x(), g_appInfoPtr->m_fRate*264, g_appInfoPtr->m_fRate*300, ui->label_version->height());
    ui->label_complay->adjustSize();
    ui->label_complay->setGeometry(ui->label_version->x(), ui->label_version->y() + ui->label_version->height() + g_appInfoPtr->m_fRate*10,
                                   ui->label_complay->width(), ui->label_complay->height());
}

void envCheck::checkProc()
{
    QString sCheckStr = "";

    if(m_bDisableVirtualMachine)
    {
        ui->label_checkItem->setText(QString::fromLocal8Bit("正在检测是否在虚拟机上运行 …"));
        bool IsInsideVM;
        QString sErrMsg;
        if(IsInsideVirtualMachine(IsInsideVM, sErrMsg))
        {
            if(IsInsideVM)
            {
                m_unpasslist.push_back(QString::fromLocal8Bit("请勿在虚拟机上运行考试程序"));
                myServerLog()<<QString::fromLocal8Bit("请勿在虚拟机上运行考试程序");
            }
        }
        else if(!sErrMsg.isEmpty())
        {
            m_unpasslist.push_back(sErrMsg);
            myServerLog()<<sErrMsg;
        }
    }

    if(g_appInfoPtr->m_bDisableRemoteAssistance)
    {
        ui->label_checkItem->setText(QString::fromLocal8Bit("正在检测是否存在远程桌面 …"));
        QApplication::processEvents();

        if(CCommonTools::isUseRDP())
        {
            sCheckStr = QString::fromLocal8Bit("请检测是否开启远程桌面");
            qDebug()<<QString::fromLocal8Bit("环境检测异常,")<<sCheckStr;
        }

        ui->label_checkItem->setText(QString::fromLocal8Bit("正在检测是否存在分屏 …"));
        QApplication::processEvents();
        if(m_MonitorEnumeratorPtr->getMontorNumber() > 1)
        {
            if(sCheckStr.isEmpty())
            {
                sCheckStr = QString::fromLocal8Bit("请检测是否开启分屏");
            }
            else
            {
                sCheckStr += QString::fromLocal8Bit("、分屏");
            }
        }
    }

    if(g_appInfoPtr->m_bDisableVirtualCamera)
    {
        ui->label_checkItem->setText(QString::fromLocal8Bit("正在检测是否存在虚拟摄像头 …"));
        QApplication::processEvents();
        std::vector<CameraInfo> cameraList;
        QStringList UnpassList;
        CCommonTools::listCameraDevices(cameraList, UnpassList, m_sCameraList);
        for(CameraInfo ci : cameraList)
        {
            myServerLog()<<QString::fromLocal8Bit("摄像头信息,vid:%1,pid%2:,name:%3")
                           .arg(ci.vid).arg(ci.pid).arg(ci.name);
            if(ci.vid.empty() || ci.pid.empty())
            {
                if(UnpassList.indexOf(ci.name, Qt::CaseInsensitive) >= 0)
                {
                    if(sCheckStr.isEmpty())
                    {
                        sCheckStr = QString::fromLocal8Bit("请检测是否开启虚拟摄像头%1").arg(ci.name);
                    }
                    else
                    {
                        sCheckStr += QString::fromLocal8Bit("、%1").arg(ci.name);
                    }
                    myDebug()<<QString::fromLocal8Bit("虚拟摄像头信息,vid:%1,pid%2:,name:%3")
                                   .arg(ci.vid).arg(ci.pid).arg(ci.name);
                }

            }
        }
    }

    if(!sCheckStr.isEmpty())
    {
        m_unpasslist.push_back(sCheckStr);
        myServerLog()<<QString::fromLocal8Bit("环境检测异常,")<<sCheckStr;
    }

    sCheckStr = "";

    if(g_appInfoPtr->m_bDisableRemoteAssistance)
    {
        ui->label_checkItem->setText(QString::fromLocal8Bit("正在检测是否存在远程协助工具 …"));
        QApplication::processEvents();
        QStringList appList;
        CCommonTools::getAllAppNameList(appList, m_sRemoteList, m_sRemoteTipList);
        if(appList.count() > 0)
        {
            for(int i = 0; i < appList.count(); i++)
            {
//                if(sCheckStr.isEmpty())
//                {
                    sCheckStr = QString::fromLocal8Bit("请检测是否开启%1").arg(appList[i]);
                    m_unpasslist.push_back(sCheckStr);
//                }
//                else
//                {
//                    sCheckStr += QString::fromLocal8Bit("、%1").arg(appList[i]);
//                }
            }
        }
    }

//    if(!sCheckStr.isEmpty())
//    {
//        m_unpasslist.push_back(sCheckStr);
//        myServerLog()<<QString::fromLocal8Bit("环境检测异常,")<<sCheckStr;
//    }

    if(m_unpasslist.count() > 0)
    {
        emit checkUnpass();
        return;
    }

    CHttpRequestPackage hrp;
    hrp.sUri = QString("https://%1/oe_client/pc/upgrade.json").arg(g_appInfoPtr->m_sEscDomain);
    hrp.nRequestType = RequestType::rtUpgrade;
    g_httpBllPtr->getUrl(hrp);

}


bool envCheck::IsInsideVirtualMachine(bool &IsInsideVM, QString &sErrMsg)
{
    typedef bool(_stdcall *VMCfn)(void);

    //需要的时候调用DLL
    HMODULE hModule = LoadLibrary(L"VMC.dll");
    if (NULL == hModule)
    {
        sErrMsg = QString::fromLocal8Bit("程序文件丢失，请重新安装！");
        return false;
    }

    VMCfn fn = (VMCfn)GetProcAddress(hModule, "IsIVM");
    if(NULL == fn)
    {
        sErrMsg = QString::fromLocal8Bit("");
        return false;
    }
    IsInsideVM = fn();
    //释放DLL
    FreeLibrary(hModule);

    return true;
}

void envCheck::startCheck()
{
    CHttpRequestPackage hrp;
    hrp.sUri = QString("https://%1/sys_notice/org_all.json").arg(g_appInfoPtr->m_sEscDomain);
    hrp.nRequestType = RequestType::rtSysNotice;
    g_httpBllPtr->getUrl(hrp);
}

QStringList envCheck::unpassList()
{
    return m_unpasslist;
}

void envCheck::onSysNotice(CSysNotice sysNotice)
{
    if(sysNotice.nCode == 200)
    {
        QDateTime dtStartTime = QDateTime::fromString(sysNotice.sStartTime, "yyyy-MM-dd hh:mm:ss");
        QDateTime dtEndTime = QDateTime::fromString(sysNotice.sEndTime, "yyyy-MM-dd hh:mm:ss");
        QDateTime dtNow = QDateTime::currentDateTime();
        if(sysNotice.bEnable && dtNow < dtEndTime && dtNow > dtStartTime)
        {
            if(popMsg(sysNotice.sContent, sysNotice.sTitle, this) == QDialog::Rejected)
            {
                emit sysUpadte();
            }
            else
            {
                CHttpRequestPackage hrp;
                hrp.sUri = QString("https://%1/org_properties/byOrgDomain/%2.ecs.qmth.com.cn/studentClientConfig.json")
                        .arg(g_appInfoPtr->m_sEscDomain).arg(g_appInfoPtr->m_sOrgPrefix);
                hrp.nRequestType = RequestType::rtStudentClientConfig;
                g_httpBllPtr->getUrl(hrp);
            }

        }
        else
        {
            CHttpRequestPackage hrp;
            hrp.sUri = QString("https://%1/org_properties/byOrgDomain/%2.ecs.qmth.com.cn/studentClientConfig.json")
                    .arg(g_appInfoPtr->m_sEscDomain).arg(g_appInfoPtr->m_sOrgPrefix);
            hrp.nRequestType = RequestType::rtStudentClientConfig;
            g_httpBllPtr->getUrl(hrp);
//            checkProc();
        }
    }
    else
    {
        m_unpasslist.push_back(QString::fromLocal8Bit("网络连接不畅"));
        emit checkUnpass();
    }
}

void envCheck::onUpgrade(CUpgrade upgrade)
{
    if(upgrade.nCode == 200)
    {
        bool bUpdateVersion = false;

        if(g_appInfoPtr->m_nVersionId != upgrade.nBuild)
        {
            g_appInfoPtr->m_nVersionId = upgrade.nBuild;
            g_appInfoPtr->m_sVersionCode = upgrade.sVersion;
            g_appInfoPtr->m_sUpgradeUrl = upgrade.sUpgradeUrl;

            bUpdateVersion = true;
        }

        emit checkpassed(bUpdateVersion);
    }
    else
    {
        m_unpasslist.push_back(QString::fromLocal8Bit("网络连接不畅"));
        emit checkUnpass();
    }
}


