/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qnetworkconfigmanager_p.h"
#include "qbearerplugin_p.h"

#include <QtCore/qdebug.h>
#include <QtCore/qtimer.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qthread.h>
#include <QtCore/private/qcoreapplication_p.h>
#include <QtCore/private/qlocking_p.h>
#include <QtCore/private/qthread_p.h>

#include <QtCore/qbytearray.h>
#include <QtCore/qglobal.h>

#include <utility>


#ifndef QT_NO_BEARERMANAGEMENT

QT_BEGIN_NAMESPACE

QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
    : QObject(), pollTimer(nullptr),
      loader(QBearerEngineFactoryInterface_iid, QLatin1String("/bearer")),
      forcedPolling(0), firstUpdate(true)
{
    qRegisterMetaType<QNetworkConfiguration>();
    qRegisterMetaType<QNetworkConfigurationPrivatePointer>();
}

void QNetworkConfigurationManagerPrivate::initialize()
{
    //Two stage construction, because we only want to do this heavyweight work for the winner of the Q_GLOBAL_STATIC race.
    bearerThread = new QDaemonThread();
    bearerThread->setObjectName(QStringLiteral("Qt bearer thread"));

    bearerThread->moveToThread(QCoreApplicationPrivate::mainThread()); // because cleanup() is called in main thread context.
    moveToThread(bearerThread);
    bearerThread->start();
    updateConfigurations();
}

QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate()
{
    QMutexLocker locker(&mutex);

    qDeleteAll(sessionEngines);
    sessionEngines.clear();
    if (bearerThread)
        bearerThread->quit();
}

void QNetworkConfigurationManagerPrivate::cleanup()
{
    QThread* thread = bearerThread;
    deleteLater();
    if (thread->wait(QDeadlineTimer(5000)))
        delete thread;
}

QNetworkConfiguration QNetworkConfigurationManagerPrivate::defaultConfiguration() const
{
    QMutexLocker locker(&mutex);

    for (QBearerEngine *engine : sessionEngines) {
        QNetworkConfigurationPrivatePointer ptr = engine->defaultConfiguration();
        if (ptr) {
            QNetworkConfiguration config;
            config.d = ptr;
            return config;
        }
    }

    // Engines don't have a default configuration.

    // Return first active snap
    QNetworkConfigurationPrivatePointer defaultConfiguration;

    for (QBearerEngine *engine : sessionEngines) {
        const auto locker = qt_scoped_lock(engine->mutex);

        for (const auto &ptr : qAsConst(engine->snapConfigurations)) {
            const auto locker = qt_scoped_lock(ptr->mutex);

            if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
                QNetworkConfiguration config;
                config.d = ptr;
                return config;
            } else if (!defaultConfiguration) {
                if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered)
                    defaultConfiguration = ptr;
            }
        }
    }

    // No Active SNAPs return first Discovered SNAP.
    if (defaultConfiguration) {
        QNetworkConfiguration config;
        config.d = defaultConfiguration;
        return config;
    }

    /*
        No Active or Discovered SNAPs, find the perferred access point.
        The following priority order is used:

            1. Active Ethernet
            2. Active WLAN
            3. Active Other
            4. Discovered Ethernet
            5. Discovered WLAN
            6. Discovered Other
    */

    for (QBearerEngine *engine : sessionEngines) {

        QMutexLocker locker(&engine->mutex);

        for (const auto &ptr : qAsConst(engine->accessPointConfigurations)) {

            QMutexLocker configLocker(&ptr->mutex);
            QNetworkConfiguration::BearerType bearerType = ptr->bearerType;

            if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered) {
                if (!defaultConfiguration) {
                    defaultConfiguration = ptr;
                } else {
                    QMutexLocker defaultConfigLocker(&defaultConfiguration->mutex);

                    if (defaultConfiguration->state == ptr->state) {
                        switch (defaultConfiguration->bearerType) {
                        case QNetworkConfiguration::BearerEthernet:
                            // do nothing
                            break;
                        case QNetworkConfiguration::BearerWLAN:
                            // Ethernet beats WLAN
                            defaultConfiguration = ptr;
                            break;
                        default:
                            // Ethernet and WLAN beats other
                            if (bearerType == QNetworkConfiguration::BearerEthernet ||
                                bearerType == QNetworkConfiguration::BearerWLAN) {
                                defaultConfiguration = ptr;
                            }
                        }
                    } else {
                        // active beats discovered
                        if ((defaultConfiguration->state & QNetworkConfiguration::Active) !=
                            QNetworkConfiguration::Active) {
                            defaultConfiguration = ptr;
                        }
                    }
                }
            }
        }
    }

    // No Active InternetAccessPoint return first Discovered InternetAccessPoint.
    if (defaultConfiguration) {
        QNetworkConfiguration config;
        config.d = defaultConfiguration;
        return config;
    }

    return QNetworkConfiguration();
}

QList<QNetworkConfiguration> QNetworkConfigurationManagerPrivate::allConfigurations(QNetworkConfiguration::StateFlags filter) const
{
    QList<QNetworkConfiguration> result;

    QMutexLocker locker(&mutex);

    for (QBearerEngine *engine : sessionEngines) {

        const auto locker = qt_scoped_lock(engine->mutex);

        //find all InternetAccessPoints
        for (const auto &ptr : qAsConst(engine->accessPointConfigurations)) {
            const auto locker = qt_scoped_lock(ptr->mutex);

            if ((ptr->state & filter) == filter) {
                QNetworkConfiguration pt;
                pt.d = ptr;
                result << pt;
            }
        }

        //find all service networks
        for (const auto &ptr : qAsConst(engine->snapConfigurations)) {
            const auto locker = qt_scoped_lock(ptr->mutex);

            if ((ptr->state & filter) == filter) {
                QNetworkConfiguration pt;
                pt.d = ptr;
                result << pt;
            }
        }
    }

    return result;
}

QNetworkConfiguration QNetworkConfigurationManagerPrivate::configurationFromIdentifier(const QString &identifier) const
{
    QNetworkConfiguration item;

    const auto locker = qt_scoped_lock(mutex);

    for (QBearerEngine *engine : sessionEngines) {
        const auto locker = qt_scoped_lock(engine->mutex);
        if (auto ptr = engine->accessPointConfigurations.value(identifier)) {
            item.d = std::move(ptr);
            break;
        }
        if (auto ptr = engine->snapConfigurations.value(identifier)) {
            item.d = std::move(ptr);
            break;
        }
        if (auto ptr = engine->userChoiceConfigurations.value(identifier)) {
            item.d = std::move(ptr);
            break;
        }
    }

    return item;
}

bool QNetworkConfigurationManagerPrivate::isOnline() const
{
    const auto locker = qt_scoped_lock(mutex);

    // We need allConfigurations since onlineConfigurations is filled with queued connections
    // and thus is not always (more importantly just after creation) up to date
    return !allConfigurations(QNetworkConfiguration::Active).isEmpty();
}

QNetworkConfigurationManager::Capabilities QNetworkConfigurationManagerPrivate::capabilities() const
{
    const auto locker = qt_scoped_lock(mutex);

    QNetworkConfigurationManager::Capabilities capFlags;

    for (QBearerEngine *engine : sessionEngines)
        capFlags |= engine->capabilities();

    return capFlags;
}

void QNetworkConfigurationManagerPrivate::configurationAdded(QNetworkConfigurationPrivatePointer ptr)
{
    const auto locker = qt_scoped_lock(mutex);

    if (!firstUpdate) {
        QNetworkConfiguration item;
        item.d = ptr;
        emit configurationAdded(item);
    }

    auto ptrLocker = qt_unique_lock(ptr->mutex);
    if (ptr->state == QNetworkConfiguration::Active) {
        const auto id = ptr->id;
        ptrLocker.unlock();
        onlineConfigurations.insert(id);
        if (!firstUpdate && onlineConfigurations.count() == 1)
            emit onlineStateChanged(true);
    }
}

void QNetworkConfigurationManagerPrivate::configurationRemoved(QNetworkConfigurationPrivatePointer ptr)
{
    const auto locker = qt_scoped_lock(mutex);

    {
        const auto locker = qt_scoped_lock(ptr->mutex);
        ptr->isValid = false;
    }

    if (!firstUpdate) {
        QNetworkConfiguration item;
        item.d = ptr;
        emit configurationRemoved(item);
    }

    onlineConfigurations.remove(ptr->id);
    if (!firstUpdate && onlineConfigurations.isEmpty())
        emit onlineStateChanged(false);
}

void QNetworkConfigurationManagerPrivate::configurationChanged(QNetworkConfigurationPrivatePointer ptr)
{
    const auto locker = qt_scoped_lock(mutex);

    if (!firstUpdate) {
        QNetworkConfiguration item;
        item.d = ptr;
        emit configurationChanged(item);
    }

    bool previous = !onlineConfigurations.isEmpty();

    {
        const auto locker = qt_scoped_lock(ptr->mutex);
        if (ptr->state == QNetworkConfiguration::Active)
            onlineConfigurations.insert(ptr->id);
        else
            onlineConfigurations.remove(ptr->id);
    }

    bool online = !onlineConfigurations.isEmpty();

    if (!firstUpdate && online != previous)
        emit onlineStateChanged(online);
}

void QNetworkConfigurationManagerPrivate::updateConfigurations()
{
    typedef QMultiMap<int, QString> PluginKeyMap;
    typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator;

    auto locker = qt_unique_lock(mutex);

    if (firstUpdate) {
        if (qobject_cast<QBearerEngine *>(sender()))
            return;

        updating = false;

        bool envOK  = false;
        const int skipGeneric = qEnvironmentVariableIntValue("QT_EXCLUDE_GENERIC_BEARER", &envOK);
        QBearerEngine *generic = nullptr;
        QFactoryLoader *l = &loader;
        const PluginKeyMap keyMap = l->keyMap();
        const PluginKeyMapConstIterator cend = keyMap.constEnd();
        QStringList addedEngines;
        for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) {
            const QString &key = it.value();
            if (addedEngines.contains(key))
                continue;

            addedEngines.append(key);
            if (QBearerEngine *engine = qLoadPlugin<QBearerEngine, QBearerEnginePlugin>(l, key)) {
                if (key == QLatin1String("generic"))
                    generic = engine;
                else
                    sessionEngines.append(engine);

                engine->moveToThread(bearerThread);

                connect(engine, SIGNAL(updateCompleted()),
                        this, SLOT(updateConfigurations()),
                        Qt::QueuedConnection);
                connect(engine, SIGNAL(configurationAdded(QNetworkConfigurationPrivatePointer)),
                        this, SLOT(configurationAdded(QNetworkConfigurationPrivatePointer)),
                        Qt::QueuedConnection);
                connect(engine, SIGNAL(configurationRemoved(QNetworkConfigurationPrivatePointer)),
                        this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer)),
                        Qt::QueuedConnection);
                connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)),
                        this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer)),
                        Qt::QueuedConnection);
            }
        }

        if (generic) {
            if (!envOK || skipGeneric <= 0)
                sessionEngines.append(generic);
            else
                delete generic;
        }
    }

    QBearerEngine *engine = qobject_cast<QBearerEngine *>(sender());
    if (engine && !updatingEngines.isEmpty())
        updatingEngines.remove(engine);

    if (updating && updatingEngines.isEmpty()) {
        updating = false;
        emit configurationUpdateComplete();
    }

    if (engine && !pollingEngines.isEmpty()) {
        pollingEngines.remove(engine);
        if (pollingEngines.isEmpty())
            startPolling();
    }

    if (firstUpdate) {
        firstUpdate = false;
        const QList<QBearerEngine*> enginesToInitialize = sessionEngines; //shallow copy the list in case it is modified when we unlock mutex
        locker.unlock();
        for (QBearerEngine* engine : enginesToInitialize)
            QMetaObject::invokeMethod(engine, "initialize", Qt::BlockingQueuedConnection);
    }
}

void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate()
{
    const auto locker = qt_scoped_lock(mutex);

    if (sessionEngines.isEmpty()) {
        emit configurationUpdateComplete();
        return;
    }

    updating = true;

    for (QBearerEngine *engine : qAsConst(sessionEngines)) {
        updatingEngines.insert(engine);
        QMetaObject::invokeMethod(engine, "requestUpdate");
    }
}

QList<QBearerEngine *> QNetworkConfigurationManagerPrivate::engines() const
{
    const auto locker = qt_scoped_lock(mutex);

    return sessionEngines;
}

void QNetworkConfigurationManagerPrivate::startPolling()
{
    const auto locker = qt_scoped_lock(mutex);
    if (!pollTimer) {
        pollTimer = new QTimer(this);
        bool ok;
        int interval = qEnvironmentVariableIntValue("QT_BEARER_POLL_TIMEOUT", &ok);
        if (!ok)
            interval = 10000;//default 10 seconds
        pollTimer->setInterval(interval);
        pollTimer->setSingleShot(true);
        connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollEngines()));
    }

    if (pollTimer->isActive())
        return;

    for (QBearerEngine *engine : qAsConst(sessionEngines)) {
        if (engine->requiresPolling() && (forcedPolling || engine->configurationsInUse())) {
            pollTimer->start();
            break;
        }
    }
    performAsyncConfigurationUpdate();
}

void QNetworkConfigurationManagerPrivate::pollEngines()
{
    const auto locker = qt_scoped_lock(mutex);

    for (QBearerEngine *engine : qAsConst(sessionEngines)) {
        if (engine->requiresPolling() && (forcedPolling || engine->configurationsInUse())) {
            pollingEngines.insert(engine);
            QMetaObject::invokeMethod(engine, "requestUpdate");
        }
    }
}

void QNetworkConfigurationManagerPrivate::enablePolling()
{
    const auto locker = qt_scoped_lock(mutex);

    ++forcedPolling;

    if (forcedPolling == 1)
        QMetaObject::invokeMethod(this, "startPolling");
}

void QNetworkConfigurationManagerPrivate::disablePolling()
{
    const auto locker = qt_scoped_lock(mutex);

    --forcedPolling;
}

QT_END_NAMESPACE

#endif // QT_NO_BEARERMANAGEMENT
