#include "config.h"
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QDebug>
#include <QFile>
#include <QDir>
#include <QSettings>
#include <QSerialPortInfo>

config::config() {
    devUuid = getDeviceUUID();
    updateSerialPortList();
}

QString config::getDeviceUUID(void)
{
    QFile file("/sys/class/dmi/id/product_uuid");
    if (!file.open(QIODevice::ReadOnly)) {
        return QString(); // 无法打开文件
    }

    QString uuid = file.readAll();
    uuid = uuid.trimmed(); // 去除可能的空格
    uuid = uuid.replace("-", "");
    return uuid;
}

void config::configWrite(void)
{
    QFile file(configfile);
#ifndef Q_OS_WIN
    QDir mdir;
    if(!mdir.exists(configpath))
    {
        mdir.mkpath(configpath);
    }
#endif
    if (!file.open(QIODevice::WriteOnly))
    {
        qDebug() << "open config.xml with WriteOnly failure!";
        return;
    }
    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true); // 使输出格式化
    xmlWriter.writeStartDocument();
    xmlWriter.writeStartElement("config");
    //device
    xmlWriter.writeStartElement("device");
    xmlWriter.writeTextElement("devInit", QString::number(devInit));
    xmlWriter.writeTextElement("devUuid", devUuid);
    xmlWriter.writeTextElement("logfileStat", QString::number(logfileStat));
    xmlWriter.writeTextElement("heartTime", QString::number(heartTime));
    xmlWriter.writeTextElement("loginTimeout", QString::number(loginTimeout));
    xmlWriter.writeTextElement("lockCloseTimeout", QString::number(lockCloseTimeout));
    xmlWriter.writeTextElement("readBee", QString::number(readBee));
    xmlWriter.writeEndElement(); // device
    //rfid
    xmlWriter.writeStartElement("rfid");
    xmlWriter.writeTextElement("rfidInit", QString::number(rfidInit));
    xmlWriter.writeTextElement("rfidPort", rfidPort);
    xmlWriter.writeTextElement("rfidBaud", QString::number(rfidBaud));
    xmlWriter.writeTextElement("rfidPower", QString::number(rfidPower));
    xmlWriter.writeTextElement("rfidSetTime", QString::number(rfidSetTime));
    xmlWriter.writeTextElement("rfidWorkTime", QString::number(rfidWorkTime));
    xmlWriter.writeEndElement(); // rfid
    //lock
    xmlWriter.writeStartElement("lock");
    xmlWriter.writeTextElement("lockInit", QString::number(lockInit));
    xmlWriter.writeTextElement("lockPort", lockPort);
    xmlWriter.writeTextElement("lockBaud", QString::number(lockBaud));
    xmlWriter.writeEndElement(); // lock
    //server
    xmlWriter.writeStartElement("server");
    xmlWriter.writeTextElement("httpHost", httpHost);
    xmlWriter.writeStartElement("httpPort");
    xmlWriter.writeEndElement(); // httpPort
    xmlWriter.writeEndElement(); // server

    //param
    xmlWriter.writeStartElement("param");
    xmlWriter.writeTextElement("usernameLogin_url", usernameLogin_url);
    xmlWriter.writeTextElement("cardLogin_url", cardLogin_url);
    xmlWriter.writeTextElement("logout_url", logout_url);
    xmlWriter.writeTextElement("getMaterial_url", getMaterial_url);
    xmlWriter.writeTextElement("userMaterial_url", userMaterial_url);
    xmlWriter.writeTextElement("openCabinet_url", openCabinet_url);
    xmlWriter.writeTextElement("closeCabinet_url", closeCabinet_url);
    xmlWriter.writeTextElement("updateMaterial_url", updateMaterial_url);
    xmlWriter.writeTextElement("addfinger_url", addfinger_url);
    xmlWriter.writeTextElement("fingerLogin_url", fingerLogin_url);


    xmlWriter.writeTextElement("instructionsGet_url", instructionsGet_url);

    xmlWriter.writeTextElement("getMaterialCheckPlan_url", getMaterialCheckPlan_url);
    xmlWriter.writeTextElement("getMaterialCheckForm_url", getMaterialCheckForm_url);

    xmlWriter.writeTextElement("postSaveForm_url", postSaveForm_url);
    xmlWriter.writeTextElement("postCheckSign_url", postCheckSign_url);
    xmlWriter.writeTextElement("postSubmit_url", postSubmit_url);

    xmlWriter.writeTextElement("getMaterialTypeList_url", getMaterialTypeList_url);
    xmlWriter.writeTextElement("getMaterialInfoList_url", getMaterialInfoList_url);
    xmlWriter.writeTextElement("getMaterialPropList_url", getMaterialPropList_url);
    xmlWriter.writeTextElement("getExMaterialInfoList_url", getExMaterialInfoList_url);

    xmlWriter.writeTextElement("postMaterialReplace_url", postMaterialReplace_url);
    xmlWriter.writeTextElement("postMaterialReplaceAuto_url", postMaterialReplaceAuto_url);

    xmlWriter.writeTextElement("postInsertCabinetOpenTimeout_url", postInsertCabinetOpenTimeout_url);
    xmlWriter.writeTextElement("postUpdateCabinetOpenTimeout_url", postUpdateCabinetOpenTimeout_url);
    xmlWriter.writeTextElement("getIsMaterialsLoanExceptionPage_url", getIsMaterialsLoanExceptionPage_url);

    xmlWriter.writeTextElement("getSysUserCharacteristicPage_url", getSysUserCharacteristicPage_url);
    xmlWriter.writeTextElement("getInfo_url", getInfo_url);
    xmlWriter.writeTextElement("insertUserFace_url", insertUserFace_url);
    xmlWriter.writeTextElement("loginByFace_url", loginByFace_url);

    xmlWriter.writeEndElement(); // param

    xmlWriter.writeEndElement(); // config
    xmlWriter.writeEndDocument();

    // 关闭文件
    file.close();
}

bool config::configRead(void)
{
    xmlType type = xmlType::XML_NULL;
    QString elemName = "";
    QFile file(configfile);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "open config.xml with ReadOnly failure!";
        return false;
    }
    QXmlStreamReader xml(&file);
    while (!xml.atEnd() && !xml.hasError()) {
        QXmlStreamReader::TokenType token = xml.readNext();
        switch (token) {
        case QXmlStreamReader::StartElement:
            // qDebug() << "StartElement:" << xml.name();
            if(xml.name() == QString("device")){
                type = xmlType::XML_DEVICE;
            }
            else if(xml.name() == QString("rfid")){
                type = xmlType::XML_RFID;
            }
            else if(xml.name() == QString("lock")){
                type = xmlType::XML_LOCK;
            }
            else if(xml.name() == QString("server")){
                type = xmlType::XML_SERVER;
            }
            else if(xml.name() == QString("param")){
                type = xmlType::XML_PARAM;
            }
            else{
                elemName = xml.name().toString();
            }
            break;
        case QXmlStreamReader::EndElement:
            // qDebug() << "EndElement:" << xml.name();
            break;
        case QXmlStreamReader::Characters:
            if (!xml.isWhitespace())
            {
                // qDebug() << "Characters:" << xml.text();
                if(type == xmlType::XML_DEVICE)
                {
                    getDeviceValue(elemName, xml.text().toString());
                }
                else if(type == xmlType::XML_RFID)
                {
                    getRfidValue(elemName, xml.text().toString());
                }
                else if(type == xmlType::XML_LOCK)
                {
                    getLockValue(elemName, xml.text().toString());
                }
                else if(type == xmlType::XML_SERVER)
                {
                    getServerValue(elemName, xml.text().toString());
                }
                else if(type == xmlType::XML_PARAM)
                {
                    getParamValue(elemName, xml.text().toString());
                }
            }

            break;
        default:
            break;
        }
    }

    if (xml.hasError()) {
        qDebug() << "Error:" << xml.errorString();
        return false;
    }

    return true;
}

void config::getDeviceValue(QString key, QString value)
{
    if(key == "devInit")
    {
        devInit = (value == "0")?false:true;
    }
    else if(key == "devUuid")
    {
        devUuid = value;
    }
    else if(key == "logfileStat")
    {
        logfileStat = (value == "0")?false:true;
    }
    else if(key == "heartTime")
    {
        heartTime = value.toInt();
    }
    else if(key == "loginTimeout")
    {
        loginTimeout = value.toInt();
    }
    else if(key == "lockCloseTimeout")
    {
        lockCloseTimeout = value.toInt();
    }
    else if(key == "readBee")
    {
        readBee = (value == "0")?false:true;
    }
}

void config::getRfidValue(QString key, QString value)
{
    if(key == "rfidInit")
    {
        rfidInit = (value == "0")?false:true;
    }
    else if(key == "rfidPort")
    {
        rfidPort = value;
    }
    else if(key == "rfidBaud")
    {
        rfidBaud = value.toInt();
    }
    else if(key == "rfidPower")
    {
        rfidPower = value.toInt();
    }
    else if(key == "rfidSetTime")
    {
        rfidSetTime = value.toInt();
    }
    else if(key == "rfidWorkTime")
    {
        rfidWorkTime = value.toInt();
    }
}

void config::getLockValue(QString key, QString value)
{
    if(key == "lockInit")
    {
        lockInit = (value == "0")?false:true;
    }
    else if(key == "lockPort")
    {
        lockPort = value;
    }
    else if(key == "lockBaud")
    {
        lockBaud = value.toInt();
    }
}

void config::getServerValue(QString key, QString value)
{
    if(key == "httpHost")
    {
        httpHost = value;
    }
}

void config::getParamValue(QString key, QString value)
{
    if(key == "usernameLogin_url")
    {
        usernameLogin_url = value;
    }
    else if(key == "cardLogin_url")
    {
        cardLogin_url = value;
    }
    else if(key == "logout_url")
    {
        logout_url = value;
    }
    else if(key == "userMaterial_url")
    {
        userMaterial_url = value;
    }
    else if(key == "getMaterial_url")
    {
        getMaterial_url = value;
    }
    else if(key == "openCabinet_url")
    {
        openCabinet_url = value;
    }
    else if(key == "closeCabinet_url")
    {
        closeCabinet_url = value;
    }
    else if(key == "updateMaterial_url")
    {
        updateMaterial_url = value;
    }
    else if(key == "addfinger_url")
    {
        addfinger_url = value;
    }
    else if(key == "fingerLogin_url")
    {
        fingerLogin_url = value;
    }
    else if (key == "getExMaterialInfoList_url")
    {
        getExMaterialInfoList_url = value;
    }


    else if(key == "instructionsGet_url")
    {
        instructionsGet_url = value;
    }
    else if(key == "getMaterialCheckPlan_url")
    {
        getMaterialCheckPlan_url = value;
    }
    else if(key == "getMaterialCheckForm_url")
    {
        getMaterialCheckForm_url = value;
    }
    else if(key == "postSaveForm_url")
    {
        postSaveForm_url = value;
    }
    else if (key == "postCheckSign_url")
    {
        postCheckSign_url = value;
    }
    else if (key == "postSubmit_url")
    {
        postSubmit_url = value;
    }

    else if(key == "getMaterialTypeList_url")
    {
        getMaterialTypeList_url = value;
    }
    else if (key == "getMaterialInfoList_url")
    {
        getMaterialInfoList_url = value;
    }
    else if (key == "getMaterialPropList_url")
    {
        getMaterialPropList_url = value;
    }

    else if (key == "postMaterialReplace_url")
    {
        postMaterialReplace_url = value;
    }
    else if (key == "postMaterialReplaceAuto_url")
    {
        postMaterialReplaceAuto_url = value;
    }

    else if (key == "postInsertCabinetOpenTimeout_url")
    {
        postInsertCabinetOpenTimeout_url = value;
    }
    else if (key == "postUpdateCabinetOpenTimeout_url")
    {
        postUpdateCabinetOpenTimeout_url = value;
    }
    else if (key == "getIsMaterialsLoanExceptionPage_url")
    {
        getIsMaterialsLoanExceptionPage_url = value;
    }
    else if (key == "getSysUserCharacteristicPage_url")
    {
        getSysUserCharacteristicPage_url = value;
    }
    else if (key == "getInfo_url")
    {
        getInfo_url = value;
    }
    else if (key == "insertUserFace_url")
    {
        insertUserFace_url = value;
    }
    else if (key == "loginByFace_url")
    {
        loginByFace_url = value;
    }
}


void config::updateSerialPortList()
{
    serialPortList.clear();
    const auto infos = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &info : infos) {
        serialPortList.append(info.portName());
    }
}
