#include "moduleconfmgt.h"
#include <QFileDialog>
#include <QTimer>
#include <QVBoxLayout>
#include <tbaseutil/tdataparse.h>
#include <tbaseutil/tdataresponse.h>
#include <tbaseutil/ttheme.h>
#include <topcore/topcore.h>
#include <toputil/t.h>
#include <twidget/ttabwidget.h>
#include <twidget/tuiloaderdialog.h>
#include <twidget/tmessagebox.h>
#include <twidget/tsplitter.h>
#include <twidget/tsearchentry.h>
#include <twidget/ttablechooserdialog.h>
#include <twidget/ttreeview.h>
#include "moduleconfmgtthread.h"
#include "moduleconfpanel.h"

SysModuleConfMgt::SysModuleConfMgt(const QString &iModuleNameStr, const QVariantMap &iUrlPars, QWidget *iParent):
    TopClassAbs(iParent),
    mSplitter(new TSplitter(this))
{
    this->appendLanguage("module-conf-mgt");
    this->setLicenseKey("");
    this->initModule(iModuleNameStr, iUrlPars);
    this->setStyleSheet(".ModuleConfMgt{background-color:#F5FAFD;}");

    initChooseDialog();
    initTreeView();
    initLeftWidget();
    initMiddleWidget();
    initRightWidget();
    this->setCentralWidget(mSplitter);
    mSplitter->setProperty("SS_BG", "PANEL");
    mSplitter->setProperty("SS_BORDER", 1);

    this->restoreSizeState();
    this->restoreObjectState(mTreeView);

    refreshActionState();
    mSplitter->setSizes(QList<int>() << 130 << 200 << 200);
    QTimer::singleShot(100, this, &SysModuleConfMgt::showInputPassword);
}

SysModuleConfMgt::~SysModuleConfMgt()
{
    this->saveSizeState();
    this->saveObjectState(mTreeView);
}

void SysModuleConfMgt::refreshTree(const QString &iTextStr)
{
    t::loading(this);
    QVariant data = doThreadWork(new ModuleConfMgtThread(this), "LOAD_TREE_DATA", QVariant(iTextStr));
    unloading();
    TDataResponse dataRes(data.toMap());
    if (dataRes.hasError()) {
        alertError(dataRes.errText());
        return;
    } else {
        fillTreeData(dataRes);
        alertOk(ttr("Data loaded"));
    }
    TTreeModel *treeModel = qobject_cast<TTreeModel*>(mTreeView->model());
    if (treeModel != nullptr) {
        treeModel->setRowsExpanded(treeModel->allIndexs(), false);
    }
}

void SysModuleConfMgt::refresh()
{
    QVariantList selectMapLst = mTreeView->selectedRowDataMaps();
    if (selectMapLst.length() <= 0) {
        return;
    }
    for (SysModuleConfPanel *onePanel : mPanelLst) {
        onePanel->blockSignals(true);
        onePanel->loadData(QVariantMap());
        onePanel->blockSignals(false);
    }
    QVariantMap firstMap = selectMapLst.first().toMap();
    if (firstMap.value("type").toString().trimmed().isEmpty() || firstMap.value("type").toString().trimmed().endsWith("node")) {
        return;
    }
    t::loading(this);
    QVariant data = doThreadWork(new ModuleConfMgtThread(this), "LOAD_PANEL_DATA", QVariant::fromValue(firstMap));
    unloading();
    TDataResponse dataRes(data.toMap());
    if (dataRes.hasError()) {
        alertError(dataRes.errText());
    } else {
        QVariantMap dataMap = dataRes.data().toMap();
        bool isAction = false;
        if ("action" == dataMap.value("type").toString()) {
            isAction = true;
        }
        QStringList keyLst = dataMap.keys();
        for (SysModuleConfPanel *onePanel : mPanelLst) {
            QString itsRank = onePanel->myRankIs();
            for (QString key : keyLst) {
                if (key.contains(itsRank)) {
                    QVariantMap panelDataMap{
                        {"name",dataMap.value("name").toString()},
                        {"module_name",dataMap.value("module_name").toString()},
                        {"type",dataMap.value("type").toString()},
                    };
                    if (isAction) {
                        panelDataMap.insert("attr", dataMap.value(QString("attr_%1").arg(itsRank)));
                        panelDataMap.insert("prog", dataMap.value(QString("prog_%1").arg(itsRank)));
                    } else {
                        panelDataMap.insert("text", dataMap.value(key).toString());
                    }
                    onePanel->loadData(panelDataMap);
                    break;
                }
            }
        }
        alertOk(ttr("Data loaded"));
    }
    this->hideMaskFrame();
}

void SysModuleConfMgt::showInputPassword()
{
    showMaskFrame(this);
    mPasswordDialog = new TUiloaderDialog(this);
    mPasswordDialog->setScriptEngine(APP->scriptEngine());
    mPasswordDialog->setSelf(this);
    mPasswordDialog->setTitle(ttr("Please input password"));
    mPasswordDialog->setUiStr(ui("verify").toString());
    mPasswordDialog->setModal(false);
    mPasswordDialog->buttonBox()->setButtons(QStringList() << ttr("Ok") + ":Ok:Yes");
    mPasswordDialog->setWindowModality(Qt::ApplicationModal);
    mPasswordDialog->show();
    connect(mPasswordDialog, SIGNAL(accepted()), this, SLOT(onPasswordAccept()));
    connect(mPasswordDialog, &TUiloaderDialog::rejected, [this](){
        APP->notify("mainwindow_close_tab", this->url());
    });
}

void SysModuleConfMgt::exportDevConfig()
{
    exportModuleFile("dev");
}

void SysModuleConfMgt::exportProdConfig()
{
    exportModuleFile("prod");
}

void SysModuleConfMgt::exportProjectConfig()
{
    exportModuleFile("project");
}

void SysModuleConfMgt::exportAdminConfig()
{
    exportModuleFile("admin");
}

void SysModuleConfMgt::exportUserConfig()
{
    exportModuleFile("user");
}

void SysModuleConfMgt::exportModuleFile(const QString &iTypeStr)
{
    QVariantList selectedLst;
    QVariantList allDataLst = mAllDataLst;
    for (QVariant var : mTreeView->selectedRowDataMaps()) {
        if (mDataLst.contains(var)) {
            selectedLst.append(var);
            for (QVariant var2 : mAllDataLst) {
                if (var2.toMap()["module_name"] == var.toMap()["module_name"]) {
                    allDataLst.removeOne(var2);
                }
            }
        }
    }

    mChooseDlg->loadAllData(allDataLst);
    mChooseDlg->loadSelectedData(selectedLst);
    mChooseDlg->resize(TTHEME_DP(1000), TTHEME_DP(500));
    if (mChooseDlg->exec() == QDialog::Accepted) {
        QVariantList list = mChooseDlg->selectedTableView()->allDataMap();
        if (list.count() > 0) {
            QString directory = APP->getSetting("module_conf_export_path").toString();
            directory = QFileDialog::getExistingDirectory(this, ttr("Export File"), directory,
                                                          QFileDialog::ShowDirsOnly |
                                                          QFileDialog::DontResolveSymlinks);
            APP->saveSetting("module_conf_export_path",directory);
            if (!directory.isEmpty()) {
                t::exporting(this);
                QStringList moduleField;
                QStringList aciontField;
                moduleField << "module_name";
                aciontField << "action_name";
                if (iTypeStr == "dev") {
                    moduleField << "conf_dev as conf" << "lang_dev as lang";
                    aciontField << "attr_dev as attr" << "prog_dev as prog";
                } else if (iTypeStr == "prod") {
                    moduleField << "conf_prod as conf" << "lang_prod as lang";
                    aciontField << "attr_prod as attr" << "prog_prod as prog" << "attr_dev" << "prog_dev";
                } else if (iTypeStr == "project") {
                    moduleField << "conf_project as conf" << "lang_project as lang";
                    aciontField << "attr_project as attr" << "prog_project as prog" << "attr_dev" << "prog_dev";
                } else if (iTypeStr == "admin") {
                    moduleField << "conf_admin as conf" << "lang_admin as lang";
                    aciontField << "attr_admin as attr" << "prog_admin as prog" << "attr_dev" << "prog_dev";
                } else if (iTypeStr == "user") {
                    moduleField << "conf_user as conf" << "lang_user as lang";
                    aciontField << "attr_user as attr" << "prog_user as prog" << "attr_dev" << "prog_dev";
                }
                QVariantMap pramer;
                pramer["module_list"] = list;
                pramer["action_field"] = aciontField;
                pramer["module_field"] = moduleField;
                QVariant data = doThreadWork(new ModuleConfMgtThread(this), "LOAD_MODULE_DATA", QVariant(pramer));
                TDataResponse dataRes(data.toMap());
                if (dataRes.hasError()) {
                    alertError(dataRes.errText());
                } else {
                    writeConfigFile(directory, dataRes.data().toList(), iTypeStr);
                    alertOk(ttr("Exporting finish"));
                }
                unloading();
            }
        }
    }
}

void SysModuleConfMgt::initTreeView()
{
    mTreeView = new TTreeView(this);
    mTreeDataKeyLst <<"name" << "module_name" <<"type" << "text";
    mTreeView->setDataKeyList(mTreeDataKeyLst);
    QVariantList hitems;
    hitems << TDataParse::variantList2Map(QVariantList()
                                          << "name" << "name"
                                          << "display" << ttr("Module Name")
                                          << "resizeMode" << "Interactive"
                                          << "size" << "290"
                                          << "displayRole" << "$name"
                                          << "search" << "string");
    hitems << TDataParse::variantList2Map(QVariantList()
                                          << "name" << "text"
                                          << "display" << ttr("Remark")
                                          << "resizeMode" << "Stretch"
                                          << "size" << "110"
                                          << "displayRole" << "$text");
    mTreeView->setHeaderItem(hitems);
    connect(mTreeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(refresh()));

    QMenu *tablePopup = qobject_cast<QMenu *>(uim()->getWidget("TABLEVIEW_POPUP"));
    if (tablePopup != nullptr) {
        mTreeView->setContextMenu(tablePopup);
    }
}

void SysModuleConfMgt::initLeftWidget()
{
    mLeftWidget = new QWidget(this);
    QVBoxLayout *vLayout = new QVBoxLayout(mLeftWidget);

    if (vLayout != nullptr) {
        vLayout->setMargin(0);
        vLayout->setSpacing(0);
        mLeftSearchEntry = new TSearchEntry(mLeftWidget);
        mLeftSearchEntry->setPlaceholderText(ttr("Search %1"));
        connect(mLeftSearchEntry, SIGNAL(search(QString, QVariant)), this, SLOT(onSearched(QString,QVariant)));

        vLayout->addWidget(mLeftSearchEntry);
        vLayout->addWidget(mTreeView);
        mLeftWidget->setLayout(vLayout);
        mSplitter->addWidget(mLeftWidget);
    }
}

void SysModuleConfMgt::initMiddleWidget()
{
    TTabWidget *tabWidgetLeft = new TTabWidget(this);
    SysModuleConfPanel *devPanel = new SysModuleConfPanel("sys-module-conf-panel", QVariantMap(), this);
    if (devPanel != nullptr) {
        devPanel->setMyRank("dev");
        devPanel->setToolbarVisible(false);
        devPanel->setTextReadOnly(true);
        tabWidgetLeft->addTab(devPanel, ttr("Develop"));
        mPanelLst.append(devPanel);
    }

    SysModuleConfPanel *prodPanel = new SysModuleConfPanel("sys-module-conf-panel", QVariantMap(), this);
    if (prodPanel != nullptr) {
        prodPanel->setMyRank("prod");
        tabWidgetLeft->addTab(prodPanel, ttr("Product"));
        mPanelLst.append(prodPanel);
        connect(prodPanel, SIGNAL(dataChanged(QVariant)), this, SLOT(onDataChange()));
        connect(prodPanel, SIGNAL(dataSaved(QVariant)), this, SLOT(onDataSave()));
    }

    mSplitter->addWidget(tabWidgetLeft);
}

void SysModuleConfMgt::initRightWidget()
{
    TTabWidget *mTabWidgetRight = new TTabWidget(this);
    SysModuleConfPanel *projectPanel = new SysModuleConfPanel("sys-module-conf-panel", QVariantMap(), this);
    if (projectPanel != nullptr) {
        projectPanel->setMyRank("project");
        mTabWidgetRight->addTab(projectPanel, ttr("Project"));
        mPanelLst.append(projectPanel);
        connect(projectPanel, SIGNAL(dataChanged(QVariant)), this, SLOT(onDataChange()));
        connect(projectPanel, SIGNAL(dataSaved(QVariant)), this, SLOT(onDataSave()));
    }

    SysModuleConfPanel *adminPanel = new SysModuleConfPanel("sys-module-conf-panel", QVariantMap(), this);
    if (adminPanel != nullptr) {
        adminPanel->setMyRank("admin");
        mTabWidgetRight->addTab(adminPanel, ttr("Administrator"));
        mPanelLst.append(adminPanel);
        connect(adminPanel, SIGNAL(dataChanged(QVariant)), this, SLOT(onDataChange()));
        connect(adminPanel, SIGNAL(dataSaved(QVariant)), this, SLOT(onDataSave()));
    }
#if 0
    SysModuleConfPanel *userPanel = new SysModuleConfPanel("sys-module-conf-panel", QVariantMap(), this);
    if (userPanel != nullptr) {
        userPanel->setMyRank("user");
        mTabWidgetRight->addTab(userPanel, ttr("User"));
        mPanelLst.append(userPanel);
        connect(userPanel, SIGNAL(dataChanged(QVariant)), this, SLOT(onDataChange()));
        connect(userPanel, SIGNAL(dataSaved(QVariant)), this, SLOT(onDataSave()));
    }
#endif
    mSplitter->addWidget(mTabWidgetRight);
}

void SysModuleConfMgt::fillTreeData(const TDataResponse &iDataRes)
{
    mAllDataLst = iDataRes.data().toList();
    for (QVariant var : mAllDataLst) {
        QVariantMap dataMap = var.toMap();
        QStringList keys = dataMap.keys();
        for (QString key : keys) {
            if (!mTreeDataKeyLst.contains(key)) {
                dataMap.remove(key);
            }
        }
        mDataLst.append(dataMap);
    }
    mTreeView->loadTreeData(mAllDataLst);
}

bool SysModuleConfMgt::getMatchedStrLst(const QVariant &iDataVar, const QString &iPatternStr, QStringList &iMatchedLst)
{
    if (iDataVar.type() == QVariant::Map) {
        for (QString key : iDataVar.toMap().keys()) {
            if ("CHILDREN" == key) {
                if (getMatchedStrLst(iDataVar.toMap()[key], iPatternStr, iMatchedLst)) {
                    if (!iMatchedLst.contains(iDataVar.toMap()["name"].toString())) {
                        iMatchedLst.append(iDataVar.toMap()["name"].toString());
                    }
                    return true;
                }
            }

            if ("name" == key) {
                QString str = iDataVar.toMap()[key].toString();
                if (str.toUpper().contains(iPatternStr.toUpper()) && (!iMatchedLst.contains(str))) {
                    iMatchedLst.append(str);
                    return true;
                }
            }

            return false;
        }
    } else if (iDataVar.type() == QVariant::List) {
        for (QVariant var : iDataVar.toList()){
            for (QString key : var.toMap().keys()) {
                if ("CHILDREN" == key) {
                    if (getMatchedStrLst(var.toMap()[key], iPatternStr, iMatchedLst)) {
                        if (!iMatchedLst.contains(var.toMap()[key].toString())) {
                            iMatchedLst.append(var.toMap()["name"].toString());
                        }
                        return true;
                    }
                }

                if ("name" == key) {
                    QString str = var.toMap()[key].toString();
                    if (str.toUpper().contains(iPatternStr.toUpper()) && (!iMatchedLst.contains(str))) {
                        iMatchedLst.append(str);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    return false;
}

void SysModuleConfMgt::initChooseDialog()
{
    mChooseDlg = new TTableChooserDialog(this);
    mChooseDlg->setRepetitionEnabled(false);
    mChooseDlg->setTitle(ttr("select field:"));
    connect(mChooseDlg->tableView(), SIGNAL(doubleClicked(QModelIndex)), this, SLOT(addChooseSelection(QModelIndex)));
    connect(mChooseDlg->selectedTableView(), SIGNAL(doubleClicked(QModelIndex)), this, SLOT(removeChooseSelection(QModelIndex)));
    QVariantList headeritems;
    headeritems << QVariant();
    headeritems << TDataParse::variantList2Map(QVariantList()
                                               << "name" << "name"
                                               << "display" << ttr("Module Name")
                                               << "resizeMode" << "Interactive"
                                               << "size" << "290"
                                               << "displayRole" << "$name"
                                               << "search" << "string");
    headeritems << TDataParse::variantList2Map(QVariantList()
                                               << "name" << "text"
                                               << "display" << ttr("Remark")
                                               << "resizeMode" << "Stretch"
                                               << "size" << "110"
                                               << "displayRole" << "$text");
    mChooseDlg->setDataKeyList(QStringList() << "name" << "text");
    mChooseDlg->setPrimaryKey("name");
    mChooseDlg->setHeaderItem(headeritems);
    mChooseDlg->setSearchKeys(QStringList() << "name" << "text");
    mChooseDlg->setLeftTableSelectionMode(QAbstractItemView::ExtendedSelection);
    mChooseDlg->setRightTableSelectionMode(QAbstractItemView::ExtendedSelection);
}

void SysModuleConfMgt::onSearched(const QString &iTextStr, const QVariant &iFieldsVar)
{
    //只根节点搜索
    Q_UNUSED(iFieldsVar);
    refreshTree(iTextStr.toUpper());
}

void SysModuleConfMgt::onPasswordAccept()
{
    QVariantMap dataMap = mPasswordDialog->uiLoader()->getAllValues().toVariant().toMap();
    mPasswordDialog->deleteLater();
    mPasswordDialog = nullptr;

    if (dataMap["password"].toString() == config("edit.password").toString()) {
        hideMaskFrame();
        refreshTree();
    } else {
        TMessageBox::error(this, ttr("Password mistake"));
        showInputPassword();
    }
}

void SysModuleConfMgt::onDataChange()
{
    bool isDataModified = false;
    for (SysModuleConfPanel *panel : mPanelLst) {
        if (panel->isDataModified()) {
            isDataModified = true;
            break;
        }
    }
    if (isDataModified) {
        this->showMaskFrame(mLeftWidget);
    } else {
        this->hideMaskFrame();
    }
}

void SysModuleConfMgt::onDataSave()
{
    this->hideMaskFrame();
}

void SysModuleConfMgt::addChooseSelection(const QModelIndex &iModelIndex)
{
    if (iModelIndex.isValid()) {
        QVariantList dataLst = mChooseDlg->tableView()->selectedRowDataMaps();
        if (dataLst.isEmpty()) {
            return;
        }
        mChooseDlg->selectedTableView()->appendRows(dataLst);

        if (!mChooseDlg->isRepetitionEnabled()) {
            mChooseDlg->tableView()->removeSelectedRows();
        }
    }
}

void SysModuleConfMgt::removeChooseSelection(const QModelIndex &iModelIndex)
{
    if (iModelIndex.isValid()) {
        QVariantList dataLst = mChooseDlg->selectedTableView()->selectedRowDataMaps();
        if (dataLst.isEmpty()) {
            return;
        }
        mChooseDlg->selectedTableView()->removeSelectedRows();

        if (!mChooseDlg->isRepetitionEnabled()) {
            mChooseDlg->tableView()->appendRows(dataLst);
        }
    }
}

void findEnumList(QVariantList iList, QStringList &dstLst, QString moduleName)
{
    for (auto data:iList){
        QVariantMap dataMap = data.toMap();
        if (dataMap.value("CHILDREN") != QVariant()){
            findEnumList(dataMap.value("CHILDREN").toList(), dstLst, moduleName);
        }
        else{
            if (dataMap.value("module_name") == moduleName.toUpper() && dataMap.value("type").toString() == QString("enum"))
            {
                dstLst.append(dataMap.value("name").toString());
            }
        }
    }
}

void SysModuleConfMgt::writeConfigFile(const QString &iDirectoryStr, const QVariantList &iDataLst, const QString &iTypeStr)
{
    QDir dir(iDirectoryStr);
    QStringList permissionLst;
    QStringList enumLst;
    bool isEmpty = true;
    QRegularExpression actionPermissionRe("PERMISSION\\s*:\\s*[\"'][^\"']*[\"']");

    for (QVariant module : iDataLst) {
        isEmpty = true;
        QVariantMap moduleInfo = module.toMap();
        QString moduleName = moduleInfo["module_name"].toString().toLower();
        dir.mkdir(moduleName);

        QDir moduleDir(iDirectoryStr + "/" + moduleName);
        QVariantList actionLst = moduleInfo["action"].toList();
        if (actionLst.count() > 0) {
            moduleDir.mkdir("actions");
            moduleDir.cd("actions");
            for (QVariant action : actionLst) {
                QVariantMap actionInfo = action.toMap();
                QString actionName = actionInfo["action_name"].toString();
                QString path = QString("%1/%2.js").arg(moduleDir.path()).arg(actionName);
                QStringList strLst;
                QString progStr = actionInfo["prog"].toString().trimmed();
                QString attrStr = actionInfo["attr"].toString().trimmed();
                if (!attrStr.isEmpty() || !progStr.isEmpty()) {
                    if (progStr.isEmpty()) {
                        progStr = actionInfo["prog_dev"].toString();
                    }
                    if (attrStr.isEmpty()) {
                        attrStr = actionInfo["attr_dev"].toString();
                    }

                    strLst.append(progStr);
                    strLst.append("");
                    strLst.append("/*---ACTION---");
                    QRegularExpressionMatch macth = actionPermissionRe.match(attrStr);
                    if (macth.hasMatch()) {
                        permissionLst.append(macth.captured().replace(QRegularExpression("PERMISSION\\s*:\\s*"),"")
                                             .replace(QRegularExpression("[\"']"),""));
                    }
                    strLst.append(attrStr);
                    strLst.append("---ACTION---*/");
                    writeFile(path, strLst);
                    isEmpty = false;
                }
            }
            moduleDir.cd("..");
            if (isEmpty) {
                moduleDir.rmdir("actions");
            }
        }

        QString langStr = moduleInfo["lang"].toString();
        if (!langStr.isEmpty()) {
            writeFile(QString("%1/lang.conf").arg(moduleDir.path()),langStr);
            isEmpty = false;
        }
        QString confStr = moduleInfo["conf"].toString();
        if (!confStr.isEmpty()) {
            QVariantMap dataMap = analysisModuleConf(confStr);
            QVariantList uiLst= dataMap["ui_list"].toList();
            for (QVariant ui : uiLst) {
                QVariantMap uiInfo = ui.toMap();
                writeFile(QString("%1/%2.ui.js").arg(moduleDir.path())
                          .arg(uiInfo["file_name"].toString()), uiInfo["content"].toString());
            }

            QString uimStr = dataMap["uim"].toString();
            if (!uimStr.isEmpty()) {
                writeFile(QString("%1/uim.conf").arg(moduleDir.path()), uimStr);
            }

            writeFile(QString("%1/module.conf").arg(moduleDir.path()), dataMap["module_conf"].toString());
            permissionLst.append(dataMap["permission"].toString());
            enumLst.append(dataMap["enum_list"].toStringList());
            isEmpty = false;
        }

        if (enumLst.size() > 0);
        else {
            TTreeModel * model = qobject_cast<TTreeModel*>(mTreeView->model());
            if (model == nullptr)
                return;
            findEnumList(model->allDataMap(), enumLst, moduleName);
        }

        if (isEmpty) {
            dir.rmdir(moduleName);
        }
    }

    writePermissionAndEnumFile(iDirectoryStr, permissionLst, enumLst, iTypeStr);
}

void SysModuleConfMgt::writePermissionAndEnumFile(const QString &iDirectoryStr, const QStringList &iPermissionLst, const QStringList &iEnumLst, const QString &iTypeStr)
{
    QVariantMap parmer{
        {"permission_list", iPermissionLst},
        {"permission_field", QStringList()<<QString("conf_%1 as conf").arg(iTypeStr)<<"permission_name"},
            {"enum_list", iEnumLst},
            {"enum_field", QStringList()<<QString("conf_%1 as conf").arg(iTypeStr) << "enum_name"}
            };
                QVariant data = doThreadWork(new ModuleConfMgtThread(this), "LOAD_PERMISSION_AND_ENUM_DATA", QVariant(parmer));
                TDataResponse dataRes(data.toMap());
                if (dataRes.hasError()) {
                    alertError(dataRes.errText());
                } else {
                    QVariantMap data = dataRes.data().toMap();
                    QVariantList permissionLst = data["permission"].toList();
                    QVariantList enumLst = data["enum"].toList();
                    QDir dir(iDirectoryStr);

                    if (permissionLst.count() > 0) {
                        QString path = QString("%1/%2").arg(iDirectoryStr).arg("__sys_permission__");
                        dir.mkpath(path);
                        for (QVariant permission : permissionLst) {
                            QVariantMap permissionInfo = permission.toMap();
                            QString contentStr = permissionInfo["conf"].toString();
                            if (!contentStr.isEmpty()) {
                                writeFile(QString("%1/%2.conf").arg(path).arg(permissionInfo["permission_name"].toString()), contentStr);
                            }
                        }
                    }

                    if (enumLst.count() > 0) {
                        QString path = QString("%1/%2").arg(iDirectoryStr).arg("__sys_enum__");
                        dir.mkpath(path);
                        for (QVariant enu : enumLst) {
                            QVariantMap enumInfo = enu.toMap();
                            QString contentStr = enumInfo["conf"].toString();
                            if (!contentStr.isEmpty()) {
                                writeFile(QString("%1/%2.conf").arg(path).arg(enumInfo["enum_name"].toString()), contentStr);
                            }
                        }
                    }
                }
            }

            QVariantMap SysModuleConfMgt::analysisModuleConf(const QString &iConfStr)
            {
                QVariantMap result;
                QRegularExpression modulePermissionRe("sys_open_right\\s*:\\s*[\"'][^\"']*[\"']");
                QRegularExpression moduleEnumRe("sys_enum_list\\s*:\\s*\\[[^\\[]*\\]");
                QString permission;
                QStringList enumLst;
                QStringList confLst = iConfStr.split(QRegularExpression(",*\\s*\"sys_ui\":\\s*{\\s*"));
                QString uiStr = confLst.last();
                QRegularExpression re("}\\s*$");
                uiStr.replace(re,"");
                QStringList uiStrList = uiStr.split("\"\"\"");
                QVariantList uiList;

                while (1) {
                    if (uiStrList.count() < 2) {
                        break;
                    }
                    QString fileName = uiStrList.first();
                    fileName.replace(QRegularExpression("[\\\":,\\n]*"), "");
                    uiStrList.removeFirst();
                    QString content = uiStrList.first();
                    uiStrList.removeFirst();
                    uiList.append(QVariantMap{
                                      {"file_name",fileName},
                                      {"content",content}
                                  });
                }
                result["ui_list"] = uiList;

                QStringList conf = confLst.first().split(QRegularExpression(",*\\s*\"sys_uim\":\\s*{\\s*"));
                if (conf.count() == 2) {
                    QString uimStr = conf.last();
                    result["uim"] = uimStr.replace(re,"");
                }
                QString moduleConf = conf.first();
                result["module_conf"] = moduleConf;

                QRegularExpressionMatch permissionMatch = modulePermissionRe.match(moduleConf);
                if (permissionMatch.hasMatch()) {
                    permission = permissionMatch.captured().replace(QRegularExpression("sys_open_right\\s*:\\s*"),"")
                            .replace(QRegularExpression("[\"']"),"");
                }

                QRegularExpressionMatch moduleMatch = moduleEnumRe.match(moduleConf);
                if (moduleMatch.hasMatch()) {
                    QStringList tempEnumLst = moduleMatch.captured().replace(QRegularExpression("sys_enum_list\\s*:\\s*\\["),"")
                            .replace("]", "").trimmed().split(",");
                    for (QString enumStr : tempEnumLst) {
                        enumLst.append(enumStr.trimmed().replace("\"", ""));
                    }
                }

                result["permission"] = permission;
                result["enum_list"] = enumLst;
                return result;
            }

            void SysModuleConfMgt::writeFile(const QString &iFilePath, const QStringList &iInfoLst)
            {
                writeFile(iFilePath, iInfoLst.join("\n"));
            }

            void SysModuleConfMgt::writeFile(const QString &iFilePath, const QString &iInfoStr)
            {
                QFile targetFile(iFilePath);
                if (targetFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
                    targetFile.write(iInfoStr.toUtf8());
                    targetFile.close();
                }
            }