// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "networkinterprocesser.h"
#include "objectmanager.h"
#include "networkdetailinterrealize.h"

#include "dslcontrollerinter.h"
#include "hotspotcontrollerinter.h"
#include "networkdetails.h"
#include "networkdevicebase.h"
#include "proxycontrollerinter.h"
#include "vpncontrollerinter.h"
#include "wireddevice.h"
#include "wirelessdevice.h"
#include "deviceinterrealize.h"

namespace dde {
namespace network {

const static QString networkService = "org.deepin.dde.Network1";
const static QString networkPath = "/org/deepin/dde/Network1";

#define CHANGE_CONNECTIONS "ConnectionsChanged"
#define CHANGE_ACTIVECONNECTIONS "ActiveConnectionsChanged"
#define CHANGE_WIRELESSACCESSPOINTS "WirelessAccessPointsChanged"

NetworkInterProcesser::NetworkInterProcesser(bool sync, QObject *parent)
    : NetworkProcesser(parent)
    , m_proxyController(Q_NULLPTR)
    , m_vpnController(Q_NULLPTR)
    , m_dslController(Q_NULLPTR)
    , m_hotspotController(Q_NULLPTR)
    , m_networkInter(new NetworkInter(networkService, networkPath, QDBusConnection::sessionBus(), this))
    , m_connectivity(Connectivity::Full)
    , m_sync(sync)
    , m_changedTimer(new QTimer(this))
    , m_needDetails(false)
{
    initConnection();
    initDeviceService();
}

NetworkInterProcesser::~NetworkInterProcesser()
{
}

void NetworkInterProcesser::initNetData(NetworkInter *networkInt)
{
    onDevicesChanged(networkInt->devices());
    doChangeConnectionList(networkInt->connections());
    doChangeAccesspoint(networkInt->wirelessAccessPoints());
    doChangeActiveConnections(networkInt->activeConnections());
}

void NetworkInterProcesser::updateSync(const bool sync)
{
    m_sync = sync;
    m_networkInter->setSync(sync);
}

void NetworkInterProcesser::initDeviceService()
{
    m_networkInter->setSync(m_sync);
    if (m_sync) {
        // 同步的方式来获取设备列表和连接列表
        initNetData(m_networkInter);
    } else {
        // 异步的方式获取设备列表和连接列表
        QDBusReply<bool> req = QDBusConnection::sessionBus().interface()->isServiceRegistered(networkService);
        if (!req.value()) {
            QDBusServiceWatcher *serviceWatcher = new QDBusServiceWatcher(this);
            serviceWatcher->setConnection(QDBusConnection::sessionBus());
            serviceWatcher->addWatchedService(networkService);
            connect(serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, [ = ] {
                NetworkInter netInter(networkService, networkPath, QDBusConnection::sessionBus(), this);
                initNetData(&netInter);
                serviceWatcher->deleteLater();
            });
        } else {
            // 在异步状态下，这里必须调用一次相关的接口来获取数据，否则就不会触发相关的信号
            initNetData(m_networkInter);
        }
    }
}

void NetworkInterProcesser::initConnection()
{
    // 定为100毫秒内，基本上连接、活动连接和热点发生变化的时候都会在100毫秒内发出信号
    // 这里需要用一个timer来执行，因为在实际情况中，ConnectionsChanged信号和ActiveConnectionsChanged信号发出的前后顺序
    // 可能会乱，如果先发送ActiveConnectionsChanged，而此时ConnectionsChanged信号却还没有发出来，此时连接列表可能为空(初次启动)
    // 导致后发出的ConnectionsChanged中的所有的连接获取到的连接状态可能是错误的，所以此处用一个定时器来接收，这样就算发送的顺序是乱的，
    // 但是它们都能在100毫秒内全部返回，这样在定时器里按照顺序来处理这些信号的数据，保证数据的准确性
    m_changedTimer->setInterval(100);
    auto onDataChanged = [ this ](const char *infoName, const QString infoValue) {
        // 这里需要用QStringList来保存，因为对于ActiveConnectionsChanged信号来说，在多个网卡存在的情况下，这个信号会发送多次
        // 每次的内容可能会不一样，例如断开连接，第一次发送的信号是第一个网卡的连接状态，第二次发送的信号是第二个网卡的连接状态，必须保证每个
        // 信号都能被正确接收并处理，否则就会出现信号丢失引起状态不正确的问题
        QStringList infoValues = m_changedTimer->property(infoName).toStringList();
        // 移除重复的，不能调用QStringList的removeDuplicates方法，因为这样移除可能会导致将最新的给移除引起错误
        if (infoValues.contains(infoValue))
            infoValues.removeOne(infoValue);
        infoValues << infoValue;
        m_changedTimer->setProperty(infoName, infoValues);
        if (!m_changedTimer->isActive())
            m_changedTimer->start();
    };

    connect(m_changedTimer, &QTimer::timeout, this, &NetworkInterProcesser::onConnectionInfoChanged);
    connect(m_networkInter, &NetworkInter::DevicesChanged, this, &NetworkInterProcesser::onDevicesChanged);                                     // 设备状态发生变化
    connect(m_networkInter, &NetworkInter::ConnectionsChanged, this, [ onDataChanged ](const QString &connections) {                            // 连接发生变化
        onDataChanged(CHANGE_CONNECTIONS, connections);
    });
    connect(m_networkInter, &NetworkInter::ActiveConnectionsChanged, this, [ onDataChanged ](const QString &activeConnections) {                // 当前活动连接发生变化
        onDataChanged(CHANGE_ACTIVECONNECTIONS, activeConnections);
    });
    connect(m_networkInter, &NetworkInter::WirelessAccessPointsChanged, this, [ onDataChanged ](const QString &accessPoints) {                  // 热点发生变化
        onDataChanged(CHANGE_WIRELESSACCESSPOINTS, accessPoints);
    });
    connect(m_networkInter, &NetworkInter::DeviceEnabled, this, &NetworkInterProcesser::onDeviceEnableChanged);                                 // 关闭设备或启用设备

    connect(m_networkInter, &NetworkInter::ConnectivityChanged, this, &NetworkInterProcesser::onConnectivityChanged);                           // 网络状态发生变化

    connect(m_networkInter, &NetworkInter::ActiveConnectionInfoChanged, this, [this] {
        // 同步IP地址等信息
        QDBusPendingCallWatcher *w = new QDBusPendingCallWatcher(m_networkInter->GetActiveConnectionInfo(), this);
        connect(w, &QDBusPendingCallWatcher::finished, w, &QDBusPendingCallWatcher::deleteLater);
        connect(w, &QDBusPendingCallWatcher::finished, this, [ this ](QDBusPendingCallWatcher * w) {
            QDBusPendingReply<QString> reply = *w;
            QString activeConnectionInfo = reply.value();
            activeConnInfoChanged(activeConnectionInfo);
        });
    });
}

NetworkDeviceBase *NetworkInterProcesser::findDevices(const QString &path) const
{
    // 查找指定路径的设备
    for (NetworkDeviceBase *device : m_devices) {
        if (device->path() == path)
            return device;
    }

    return Q_NULLPTR;
}

static DeviceType deviceType(const QString &type)
{
    if (type == "wireless")
        return DeviceType::Wireless;

    if (type == "wired")
        return DeviceType::Wired;

    return DeviceType::Unknown;
}

void NetworkInterProcesser::onDevicesChanged(const QString &value)
{
    if (value.isEmpty())
        return;

    bool unManager = false;
    const QJsonObject data = QJsonDocument::fromJson(value.toUtf8()).object();
    QStringList devPaths;
    QList<NetworkDeviceBase *> newDevices;
    QStringList keys = data.keys();
    for (int i = 0; i < keys.size(); i++) {
        QString key = keys[i];
        DeviceType type = deviceType(key);
        if (type == DeviceType::Unknown)
            continue;

        QJsonArray deviceList = data.value(key).toArray();
        for (const QJsonValue jsonValue : deviceList) {
            const QJsonObject &deviceInfo = jsonValue.toObject();
            const QString path = deviceInfo.value("Path").toString();
            if (!deviceInfo.value("Managed").toBool()) {
                // 如果managed为false，且在设备列表中未找到，则不添加到设备
                NetworkDeviceBase *device = findDevices(path);
                if (!device)
                    continue;

                unManager = true;
            }

            // 根据标志位InterfaceFlags判断网络连接是否有效(无线网络不需要根据这个标志位来判断，因为无线网络在开启飞行模式后，这个标志位会变成0,但是需要显示无线网卡)
            if (type != DeviceType::Wireless) {
                if (!deviceInfo.value("InterfaceFlags").isUndefined()) {
                    if (!(deviceInfo.value("InterfaceFlags").toInt() & DEVICE_INTERFACE_FLAG_UP)) {
                        qCDebug(DNC) << "Interface_flag_up: " << deviceInfo.value("Interface").toString();
                        continue;
                    }
                }
            }

            NetworkDeviceBase *device = findDevices(path);
            if (!device) {
                switch (type) {
                case DeviceType::Wireless: {
                    qCDebug(DNC) << "new Wireless Device: " << deviceInfo.value("Interface").toString();
                    DeviceInterRealize *wirelessRealize = new WirelessDeviceInterRealize(m_networkInter, nullptr);
                    device = new WirelessDevice(wirelessRealize, this);
                    wirelessRealize->updateDeviceInfo(deviceInfo);
                    break;
                }
                case DeviceType::Wired: {
                    qCDebug(DNC) << "new Wired Device: " << deviceInfo.value("Interface").toString();
                    DeviceInterRealize *wiredRealize = new WiredDeviceInterRealize(m_networkInter, nullptr);
                    device = new WiredDevice(wiredRealize, this);
                    wiredRealize->updateDeviceInfo(deviceInfo);
                    break;
                }
                default:
                    break;
                }
                if (device) {
                    newDevices << device;
                    m_devices << device;
                }
            } else {
                DeviceInterRealize *deviceRealized = static_cast<DeviceInterRealize *>(ObjectManager::instance()->deviceRealize(device));
                deviceRealized->updateDeviceInfo(deviceInfo);
            }
            if (device) {
                // 将所有的设备路径添加到缓存中
                if (!devPaths.contains(device->path()))
                    devPaths << device->path();
            }
        }
    }
    // 对设备进行排序，有线网络始终排在无线网络前面
    auto getPathIndex = [ ](const QString path)->int {
        int index = path.lastIndexOf("/");
        QString tmpIndexValue = path.mid(index + 1);
        return tmpIndexValue.toInt();
    };

    std::sort(m_devices.begin(), m_devices.end(), [ = ](NetworkDeviceBase *dev1, NetworkDeviceBase *dev2) {
        if (dev1->deviceType() == DeviceType::Wired && dev2->deviceType() == DeviceType::Wireless)
            return true;

        if (dev1->deviceType() == DeviceType::Wireless && dev2->deviceType() == DeviceType::Wired)
            return false;

        return getPathIndex(dev1->path()) < getPathIndex(dev2->path());
    });
    // 删除已经移除的设备
    QList<NetworkDeviceBase *> rmDevices;
    for (NetworkDeviceBase *device : m_devices) {
        if (!devPaths.contains(device->path()))
            rmDevices << device;
    }

    for (NetworkDeviceBase *device : rmDevices)
        m_devices.removeOne(device);

    if (newDevices.size() > 0 || rmDevices.size() > 0) {
        // 更新设备名称
        updateDeviceName();

        // 告诉外面新增的设备列表
        if (newDevices.size() > 0) {
            // 初始化设备的数据，包括设备是否可用等信息
            bool wirelessExist = false;
            for (NetworkDeviceBase *device : newDevices) {
                DeviceInterRealize *deviceInter = static_cast<DeviceInterRealize *>(ObjectManager::instance()->deviceRealize(device));
                deviceInter->initDeviceInfo();
                if (device->deviceType() == DeviceType::Wireless)
                    wirelessExist = true;
            }

            // 更新设备的时候，同时需要更新连接信息，因为可能连接的信号发生在设备更新信息之前
            updateConnectionsInfo(newDevices);
            // 如果新增的设备中存在无线网卡，则同时需要更新wlan的信息，因为存在如下情况
            // 如果关闭热点的时候，会先移除设备，然后再新增设备，此时如果不更新wlan，这种情况下，新增的那个无线设备的wlan就会为空
            if (wirelessExist)
                doChangeAccesspoint(m_networkInter->wirelessAccessPoints());
        }
        // 设备列表发生变化的同时，需要同时更新网络连接状态
        doChangeActiveConnections(m_networkInter->activeConnections());

        // 设备列表发生变化的同时，需要同时更新DSL的相关的信息，因为DSL里面用到了设备的信息，需要获取设备路径等
        updateDSLData();

        // 设备列表发生变化后，同时也需要更新设备热点的信息
        updateDeviceHotpot();

        // 发送删除的设备列表信号，此时这些设备对象还未析构，外面调用来处理响应的操作，统一在一个线程中处理
        if (rmDevices.size() > 0) {
            for (NetworkDeviceBase *device : rmDevices)
                Q_EMIT device->removed();

            Q_EMIT deviceRemoved(rmDevices);
            // 在移除设备后，需要立刻将网络详情中对应的项移除
            updateNetworkDetails();
        }

        // 需要将新增设备的信号放到更新设备数据之后，因为外部接收到新增设备信号的时候，需要更新设备信息，如果放到更新设备数据前面，则里面的数据不是最新的数据
        if (newDevices.size() > 0)
            Q_EMIT deviceAdded(newDevices);

        // 一定要将删除设备放到最后，因为在发出信号后，外面可能还会用到
        for (NetworkDeviceBase *device : rmDevices)
            device->deleteLater();
    }
    // 如果发现有Manager=false的对象，则让它等一秒后从设备列表中移除manager==false的对象，因为可能是关闭热点引起的Manager=false
    if (unManager) {
        QTimer::singleShot(1000, this, [ this ] {
            QList<NetworkDeviceBase *> unManagerDevices;
            for (NetworkDeviceBase *device : m_devices) {
                if (!device->managed())
                    unManagerDevices << device;
            }

            if (unManagerDevices.size() > 0) {
                for (NetworkDeviceBase *device : unManagerDevices)
                    m_devices.removeOne(device);

                for (NetworkDeviceBase *device : unManagerDevices)
                    Q_EMIT device->removed();

                Q_EMIT deviceRemoved(unManagerDevices);
                // 在移除设备后，需要立刻将网络详情中对应的项移除
                updateNetworkDetails();
                // 删除对象
                for (NetworkDeviceBase *device : unManagerDevices)
                    device->deleteLater();
            }
        });
    }
}

void NetworkInterProcesser::doChangedData(changedFunction func, const char *infoName)
{
    QStringList changeDatas = m_changedTimer->property(infoName).toStringList();
    if (!changeDatas.isEmpty()) {
        for (QString changeData : changeDatas)
            (this->*func)(changeData);

        changeDatas.clear();
        m_changedTimer->setProperty(infoName, changeDatas);
    }
}

void NetworkInterProcesser::onConnectionInfoChanged()
{
    // 触发数据改变的顺序，1.无线网络 2.连接信息 3.活动连接信息，理由如下
    // 连接信息中更新无线连接的时候，需要从无线网络中获取wlan数据进行同步，所以需要先同步无线网络(wlan)，
    // 活动连接信息需要更新的是已经存在的连接，因此需要先同步连接信息，活动连接信息放到最后同步
    doChangedData(&NetworkInterProcesser::doChangeAccesspoint, CHANGE_WIRELESSACCESSPOINTS);
    doChangedData(&NetworkInterProcesser::doChangeConnectionList, CHANGE_CONNECTIONS);
    doChangedData(&NetworkInterProcesser::doChangeActiveConnections, CHANGE_ACTIVECONNECTIONS);
    if (m_changedTimer->isActive())
        m_changedTimer->stop();
}

void NetworkInterProcesser::doChangeConnectionList(const QString &connections)
{
    if (connections.isEmpty())
        return;

    m_connections = QJsonDocument::fromJson(connections.toUtf8()).object();
    updateConnectionsInfo(m_devices);

    // 更新VPN的数据
    if (m_vpnController && m_connections.contains("vpn"))
        m_vpnController->updateVPNItems(m_connections.value("vpn").toArray());

    // 更新DSL的数据
    updateDSLData();

    // 更新热点的数据
    updateDeviceHotpot();

    // 向外抛出信号告知连接发生了变化
    Q_EMIT connectionChanged();
}

void NetworkInterProcesser::doChangeActiveConnections(const QString &activeConnections)
{
    // 初次进来的时候，活动连接内容为空，此时需要返回。
    // 如果不判断这个的话，那么在初始化的时候就会向外部发送activeConnectionChange信号，引起网络列表的显示的问题
    if (activeConnections.isEmpty())
        return;

    activeInfoChanged(activeConnections);
    // 同步IP地址等信息
    QDBusPendingCallWatcher *w = new QDBusPendingCallWatcher(m_networkInter->GetActiveConnectionInfo(), this);
    connect(w, &QDBusPendingCallWatcher::finished, w, &QDBusPendingCallWatcher::deleteLater);
    connect(w, &QDBusPendingCallWatcher::finished, this, [ = ](QDBusPendingCallWatcher * w) {
        QDBusPendingReply<QString> reply = *w;
        QString activeConnectionInfo = reply.value();
        activeConnInfoChanged(activeConnectionInfo);
        onConnectivityChanged(m_networkInter->connectivity());
    });
}

void NetworkInterProcesser::activeConnInfoChanged(const QString &conns)
{
    // 当没有激活的连接时，需要更新对应的连接信息和网络详细信息为空
    if (conns == "null") {
        for (NetworkDeviceBase *device : m_devices){
            DeviceInterRealize *deviceInter = static_cast<DeviceInterRealize *>(ObjectManager::instance()->deviceRealize(device));
            deviceInter->updateActiveConnectionInfo(QList<QJsonObject>());
        }
        updateNetworkDetails();
        Q_EMIT activeConnectionChange();

        return;
    }

    QJsonParseError error;
    m_activeConnectionInfo = QJsonDocument::fromJson(conns.toUtf8(), &error).array();
    if (error.error == QJsonParseError::NoError) {
        QMultiMap<NetworkDeviceBase *, QJsonObject> deviceInfoMap;
        for (QJsonValue jsonValue : m_activeConnectionInfo) {
            QJsonObject connInfo = jsonValue.toObject();
            const QString devPath = connInfo.value("Device").toString();
            NetworkDeviceBase *device = findDevices(devPath);
            if (!device)
                continue;

            deviceInfoMap.insert(device, connInfo);
        }

        for (auto it = deviceInfoMap.begin(); it != deviceInfoMap.end(); it++) {
            NetworkDeviceBase *device = it.key();
            QList<QJsonObject> json = deviceInfoMap.values(device);
            DeviceInterRealize *deviceInter = static_cast<DeviceInterRealize *>(ObjectManager::instance()->deviceRealize(device));
            deviceInter->updateActiveConnectionInfo(json);
        }
        // 对于没有发送的设备，直接让其显示空
        for (NetworkDeviceBase *device : m_devices) {
            if (!deviceInfoMap.contains(device)) {
                DeviceInterRealize *deviceInter = static_cast<DeviceInterRealize *>(ObjectManager::instance()->deviceRealize(device));
                deviceInter->updateActiveConnectionInfo(QList<QJsonObject>());
            }
        }
    } else {
        qCDebug(DNC) << "receive error connection value:" << conns;
    }
    // 同时需要更新网络信息
    updateNetworkDetails();

    Q_EMIT activeConnectionChange();
}

void NetworkInterProcesser::doChangeAccesspoint(const QString &accessPoints)
{
    if (accessPoints.isEmpty())
        return;

    const QJsonObject json = QJsonDocument::fromJson(accessPoints.toUtf8()).object();

    for (NetworkDeviceBase *device : m_devices) {
        // 只有无线网卡才会有wlan连接信息
        if (device->deviceType() == DeviceType::Wireless) {
            WirelessDevice *d = static_cast<WirelessDevice *>(device);
            if (json.contains(d->path())) {
                QJsonArray array = json.value(d->path()).toArray();

                WirelessDeviceInterRealize *deviceRealize = qobject_cast<WirelessDeviceInterRealize *>(d->deviceRealize());
                if (deviceRealize)
                    deviceRealize->updateAccesspoint(array);
            }
        }
    }
}

void NetworkInterProcesser::onDeviceEnableChanged(const QString &devicePath, bool enabled)
{
    qCInfo(DNC) << "Device enabled changed, device:" << devicePath << ", enabled" << enabled;
    NetworkDeviceBase *device = findDevices(devicePath);
    if (device) {
        DeviceInterRealize *interDevice = static_cast<DeviceInterRealize *>(ObjectManager::instance()->deviceRealize(device));
        interDevice->setDeviceEnabledStatus(enabled);
        // 如果改设备是无线设备，且支持热点，则更新热点的信息
        if (!m_hotspotController)
            return;
        // 如果当前设备是无线设备切当前设备支持热点，则更新当前设备的热点信息
        if (device->deviceType() == DeviceType::Wireless && device->supportHotspot())
            updateDeviceHotpot();
    }
}

void NetworkInterProcesser::onConnectivityChanged(uint conectivity)
{
    Connectivity conn = static_cast<Connectivity>(conectivity);
    if (conn == m_connectivity)
        return;

    qCInfo(DNC) << "conectivity:" << conectivity;
    m_connectivity = conn;
    Q_EMIT connectivityChanged(m_connectivity);
}

void NetworkInterProcesser::updateConnectionsInfo(const QList<NetworkDeviceBase *> &devices)
{
    if (devices.isEmpty() || m_connections.isEmpty())
        return;

    static QList<QPair<QString, DeviceType>> devConnInfo
        = {{ "wired", DeviceType::Wired }, { "wireless", DeviceType::Wireless }};

    for (const QPair<QString, DeviceType> &connInfo : devConnInfo) {
        if (m_connections.contains(connInfo.first)) {
            const QJsonArray &connlist = m_connections.value(connInfo.first).toArray();
            for (NetworkDeviceBase *device : devices) {
                if (device->deviceType() == connInfo.second) {
                    DeviceInterRealize *deviceInter = static_cast<DeviceInterRealize *>(ObjectManager::instance()->deviceRealize(device));
                    deviceInter->updateConnection(connlist);
                }
            }
        }
    }
}

void NetworkInterProcesser::activeInfoChanged(const QString &conns)
{
    // 当前活动连接发生变化
    m_activeConection = QJsonDocument::fromJson(conns.toUtf8()).object();
    QMap<QString, QList<QJsonObject>> devActiveConn;
    for (const QJsonValue info : m_activeConection) {
        const QJsonObject connInfo = info.toObject();
        const QJsonArray devArray = connInfo.value("Devices").toArray();
        for (const QJsonValue &value : devArray) {
            const QString devPath = value.toString();
            devActiveConn[devPath] << connInfo;
        }
    }

    // 更新DSL的活动连接信息
    if (m_dslController)
        m_dslController->updateActiveConnections(m_activeConection);

    // 更新设备的活动连接信息
    for (auto it = devActiveConn.begin(); it != devActiveConn.end(); it++) {
        const QString devPath = it.key();
        NetworkDeviceBase *device = findDevices(devPath);
        if (!device)
            continue;

        const QList<QJsonObject> devInfos = it.value();
        DeviceInterRealize *deviceInt = static_cast<DeviceInterRealize *>(ObjectManager::instance()->deviceRealize(device));
        deviceInt->updateActiveInfo(devInfos);
    }

    // 更新热点的活动连接信息
    if (m_hotspotController)
        m_hotspotController->updateActiveConnection(m_activeConection);

    // 更新VPN的活动连接信息
    if (m_vpnController)
        m_vpnController->updateActiveConnection(m_activeConection);
}

Connectivity NetworkInterProcesser::connectivity()
{
    return m_connectivity;
}

QList<NetworkDeviceBase *> NetworkInterProcesser::devices()
{
    return m_devices;
}

QList<NetworkDetails *> NetworkInterProcesser::networkDetails()
{
    if (!m_needDetails) {
        m_needDetails = true;
        updateNetworkDetails();
    }
    return ObjectManager::instance()->networkDetails();
}

void NetworkInterProcesser::updateDeviceHotpot()
{
    if (!m_hotspotController)
        return;

    m_hotspotController->updateDevices(m_devices);

    if (!m_connections.contains("wireless-hotspot"))
        return;

    const QJsonArray hotspots = m_connections.value("wireless-hotspot").toArray();
    qCDebug(DNC) << "update device hotspot" << hotspots;
    // 更新连接的信息
    m_hotspotController->updateConnections(hotspots);
}

void NetworkInterProcesser::updateNetworkDetails()
{
    if (!m_needDetails)
        return;

    QStringList devicePaths;
    for (NetworkDeviceBase *device : m_devices) {
        if (!device->isEnabled() || !device->available())
            continue;

        devicePaths << device->path();
    }

    // 删除多余的网络详情的数据
    ObjectManager *creator = ObjectManager::instance();
    creator->cleanupNetworkDetails();

    // 遍历网络详情列表，更新内存中的记录
    for (int i = 0; i < m_activeConnectionInfo.size(); i++) {
        QJsonObject activeConnection = m_activeConnectionInfo.at(i).toObject();
        QString devicePath = activeConnection.value("Device").toString();
        if (!devicePaths.contains(devicePath))
            continue;

        NetworkDetailInterRealize *detail = new NetworkDetailInterRealize;
        detail->updateData(activeConnection);
        creator->createNetworkDetail(detail);
    }
}

void NetworkInterProcesser::updateDSLData()
{
    if (!m_dslController || !m_connections.contains("pppoe"))
        return;

    m_dslController->updateDevice(m_devices);
    m_dslController->updateDSLItems(m_connections.value("pppoe").toArray());
    m_dslController->updateActiveConnections(m_activeConection);
}

ProxyController *NetworkInterProcesser::proxyController()
{
    // 因为有的地方不会调用这个接口，所以该对象延迟创建
    if (!m_proxyController)
        m_proxyController = new ProxyController_Inter(this);

    return m_proxyController;
}

VPNController *NetworkInterProcesser::vpnController()
{
    // 延迟创建
    if (!m_vpnController) {
        m_vpnController = new VPNController_Inter(m_networkInter, this);
        if (m_connections.contains("vpn"))
            m_vpnController->updateVPNItems(m_connections.value("vpn").toArray());
        m_vpnController->updateActiveConnection(m_activeConection);
    }

    return  m_vpnController;
}

DSLController *NetworkInterProcesser::dslController()
{
    // 延迟创建
    if (!m_dslController) {
        m_dslController = new DSLController_Inter(m_networkInter, this);
        updateDSLData();
    }

    return m_dslController;
}

HotspotController *NetworkInterProcesser::hotspotController()
{
    // 延迟创建
    if (!m_hotspotController) {
        m_hotspotController = new HotspotControllerInter(m_networkInter, this);
        updateDeviceHotpot();
        m_hotspotController->updateActiveConnection(m_activeConection);
    }

    return m_hotspotController;
}

}
}
