#include "config.h"

#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QDebug>
#include <QFile>
#include <QDir>
#include <QSettings>
#include <QNetworkInterface>

config* config::pInstance = nullptr;

QList<QString> getSystemMacAddresses() {
    QList<QString> macList;

    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();

    for (const QNetworkInterface &interface : interfaces) {
        if (!interface.isValid()) {
            continue;
        }

        if (interface.flags().testFlag(QNetworkInterface::IsLoopBack)) {
            continue;
        }

        QString mac = interface.hardwareAddress();
        if (mac.isEmpty() || mac == "00:00:00:00:00:00") {
            continue;
        }

        bool hasIPv4 = false;
        QList<QNetworkAddressEntry> entries = interface.addressEntries();
        for (const QNetworkAddressEntry &entry : entries) {
            if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
                hasIPv4 = true;
                break;
            }
        }
        if (!hasIPv4) {
            continue;
        }

        macList.append(mac);
    }

    return macList;
}

config::config() {
    // 测试时无法调用product_uuid文件，测试用例
    //devUuid = "CABINET_017";
    devUuid = getDeviceUUID();

    QList<QString> macList = getSystemMacAddresses();

    m_systemMACAddr = macList.isEmpty() ? "" : macList[0];
}

config *config::instance()
{
    if (!pInstance) {
        pInstance = new config;
    }
    return pInstance;
}

config *config::create(QQmlEngine *, QJSEngine *)
{
    return instance();
}

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
    //server
    xmlWriter.writeStartElement("server");
    xmlWriter.writeTextElement("httpHost", httpHost);
    xmlWriter.writeTextElement("tenant_id", tenant_id);
    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("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("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_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::getServerValue(QString key, QString value)
{
    if(key == "httpHost")
    {
        httpHost = value;
    }
    else if(key == "tenant_id")
    {
        tenant_id = 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 == "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;
    }
}
