/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins 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 "qnativewifiengine.h"
#include "platformdefs.h"
#include "../qnetworksession_impl.h"

#include <QtNetwork/private/qnetworkconfiguration_p.h>

#include <QtCore/qstringlist.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qoperatingsystemversion.h>

#include <QtCore/qdebug.h>

#ifndef QT_NO_BEARERMANAGEMENT

QT_BEGIN_NAMESPACE

WlanOpenHandleProto local_WlanOpenHandle = 0;
WlanRegisterNotificationProto local_WlanRegisterNotification = 0;
WlanEnumInterfacesProto local_WlanEnumInterfaces = 0;
WlanGetAvailableNetworkListProto local_WlanGetAvailableNetworkList = 0;
WlanQueryInterfaceProto local_WlanQueryInterface = 0;
WlanConnectProto local_WlanConnect = 0;
WlanDisconnectProto local_WlanDisconnect = 0;
WlanScanProto local_WlanScan = 0;
WlanFreeMemoryProto local_WlanFreeMemory = 0;
WlanCloseHandleProto local_WlanCloseHandle = 0;

void qNotificationCallback(WLAN_NOTIFICATION_DATA *data, QNativeWifiEngine *d)
{
    Q_UNUSED(d);

    if (data->NotificationSource == WLAN_NOTIFICATION_SOURCE_ACM) {
        switch (data->NotificationCode) {
        case wlan_notification_acm_connection_complete:
        case wlan_notification_acm_disconnected:
        case wlan_notification_acm_scan_complete:
        case wlan_notification_acm_scan_fail:
            QMetaObject::invokeMethod(d, "scanComplete", Qt::QueuedConnection);
            break;
        default:
#ifdef BEARER_MANAGEMENT_DEBUG
            qDebug() << "wlan acm notification" << (int)data->NotificationCode;
#endif
            break;
        }
    } else {
#ifdef BEARER_MANAGEMENT_DEBUG
            qDebug() << "wlan notification source" << (int)data->NotificationSource << "code" << (int)data->NotificationCode;
#endif
    }
}

QNativeWifiEngine::QNativeWifiEngine(QObject *parent)
:   QBearerEngineImpl(parent), handle(INVALID_HANDLE_VALUE)
{
    connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(closeHandle()));
}

QNativeWifiEngine::~QNativeWifiEngine()
{
    closeHandle();
}

void QNativeWifiEngine::scanComplete()
{
    QMutexLocker locker(&mutex);

    if (!available()) {
        locker.unlock();
        emit updateCompleted();
        return;
    }

    // enumerate interfaces
    WLAN_INTERFACE_INFO_LIST *interfaceList;
    DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
    if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
        qDebug("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
#endif

        locker.unlock();
        emit updateCompleted();

        return;
    }

    QStringList previous = accessPointConfigurations.keys();

    for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
        const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];

        WLAN_AVAILABLE_NETWORK_LIST *networkList;
        result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid,
                                                   3, 0, &networkList);
        if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
            qDebug("%s: WlanGetAvailableNetworkList failed with error %ld\n",
                   __FUNCTION__, result);
#endif
            continue;
        }

        QStringList seenNetworks;

        for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) {
            WLAN_AVAILABLE_NETWORK &network = networkList->Network[j];

            QString networkName;

            if (network.strProfileName[0] != 0) {
                networkName = QString::fromWCharArray(network.strProfileName);
            } else {
                networkName = QByteArray(reinterpret_cast<char *>(network.dot11Ssid.ucSSID),
                                         network.dot11Ssid.uSSIDLength);
            }

            const QString id = QString::number(qHash(QLatin1String("WLAN:") + networkName));

            previous.removeAll(id);

            QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;

            if (!(network.dwFlags & WLAN_AVAILABLE_NETWORK_HAS_PROFILE))
                state = QNetworkConfiguration::Undefined;

            if (network.strProfileName[0] != 0) {
                if (network.bNetworkConnectable) {
                    if (network.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED)
                        state = QNetworkConfiguration::Active;
                    else
                        state = QNetworkConfiguration::Discovered;
                } else {
                    state = QNetworkConfiguration::Defined;
                }
            }

            if (seenNetworks.contains(networkName))
                continue;
            else
                seenNetworks.append(networkName);

            if (accessPointConfigurations.contains(id)) {
                QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);

                bool changed = false;

                ptr->mutex.lock();

                if (!ptr->isValid) {
                    ptr->isValid = true;
                    changed = true;
                }

                if (ptr->name != networkName) {
                    ptr->name = networkName;
                    changed = true;
                }

                if (ptr->state != state) {
                    ptr->state = state;
                    changed = true;
                }

                ptr->mutex.unlock();

                if (changed) {
                    locker.unlock();
                    emit configurationChanged(ptr);
                    locker.relock();
                }
            } else {
                QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);

                ptr->name = networkName;
                ptr->isValid = true;
                ptr->id = id;
                ptr->state = state;
                ptr->type = QNetworkConfiguration::InternetAccessPoint;
                ptr->bearerType = QNetworkConfiguration::BearerWLAN;

                accessPointConfigurations.insert(id, ptr);

                locker.unlock();
                emit configurationAdded(ptr);
                locker.relock();
            }
        }

        local_WlanFreeMemory(networkList);
    }

    local_WlanFreeMemory(interfaceList);

    while (!previous.isEmpty()) {
        QNetworkConfigurationPrivatePointer ptr =
            accessPointConfigurations.take(previous.takeFirst());

        locker.unlock();
        emit configurationRemoved(ptr);
        locker.relock();
    }

    locker.unlock();
    emit updateCompleted();
}

QString QNativeWifiEngine::getInterfaceFromId(const QString &id)
{
    QMutexLocker locker(&mutex);

    if (!available())
        return QString();

    // enumerate interfaces
    WLAN_INTERFACE_INFO_LIST *interfaceList;
    DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
    if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
        qDebug("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
#endif
        return QString();
    }

    for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
        const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];

        DWORD dataSize;
        WLAN_CONNECTION_ATTRIBUTES *connectionAttributes;
        result = local_WlanQueryInterface(handle, &interface.InterfaceGuid,
                                          wlan_intf_opcode_current_connection, 0, &dataSize,
                                          reinterpret_cast<PVOID *>(&connectionAttributes), 0);
        if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
            if (result != ERROR_INVALID_STATE)
                qDebug("%s: WlanQueryInterface failed with error %ld\n", __FUNCTION__, result);
#endif

            continue;
        }

        if (qHash(QLatin1String("WLAN:") +
                  QString::fromWCharArray(connectionAttributes->strProfileName)) == id.toUInt()) {
            QString guid("{%1-%2-%3-%4%5-%6%7%8%9%10%11}");

            guid = guid.arg(interface.InterfaceGuid.Data1, 8, 16, QChar('0'));
            guid = guid.arg(interface.InterfaceGuid.Data2, 4, 16, QChar('0'));
            guid = guid.arg(interface.InterfaceGuid.Data3, 4, 16, QChar('0'));
            for (int i = 0; i < 8; ++i)
                guid = guid.arg(interface.InterfaceGuid.Data4[i], 2, 16, QChar('0'));

            local_WlanFreeMemory(connectionAttributes);
            local_WlanFreeMemory(interfaceList);

            return guid.toUpper();
        }

        local_WlanFreeMemory(connectionAttributes);
    }

    local_WlanFreeMemory(interfaceList);

    return QString();
}

bool QNativeWifiEngine::hasIdentifier(const QString &id)
{
    QMutexLocker locker(&mutex);

    if (!available())
        return false;

    // enumerate interfaces
    WLAN_INTERFACE_INFO_LIST *interfaceList;
    DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
    if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
        qDebug("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
#endif
        return false;
    }

    for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
        const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];

        WLAN_AVAILABLE_NETWORK_LIST *networkList;
        result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid,
                                                   3, 0, &networkList);
        if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
            qDebug("%s: WlanGetAvailableNetworkList failed with error %ld\n",
                   __FUNCTION__, result);
#endif
            continue;
        }

        for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) {
            WLAN_AVAILABLE_NETWORK &network = networkList->Network[j];

            QString networkName;

            if (network.strProfileName[0] != 0) {
                networkName = QString::fromWCharArray(network.strProfileName);
            } else {
                networkName = QByteArray(reinterpret_cast<char *>(network.dot11Ssid.ucSSID),
                                         network.dot11Ssid.uSSIDLength);
            }

            if (qHash(QLatin1String("WLAN:") + networkName) == id.toUInt()) {
                local_WlanFreeMemory(networkList);
                local_WlanFreeMemory(interfaceList);
                return true;
            }
        }

        local_WlanFreeMemory(networkList);
    }

    local_WlanFreeMemory(interfaceList);

    return false;
}

void QNativeWifiEngine::connectToId(const QString &id)
{
    QMutexLocker locker(&mutex);

    if (!available()) {
        locker.unlock();
        emit connectionError(id, InterfaceLookupError);
        return;
    }

    WLAN_INTERFACE_INFO_LIST *interfaceList;
    DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
    if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
        qDebug("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
#endif
        locker.unlock();
        emit connectionError(id, InterfaceLookupError);
        return;
    }

    QString profile;

    for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
        const WLAN_INTERFACE_INFO &interface = interfaceList->InterfaceInfo[i];

        WLAN_AVAILABLE_NETWORK_LIST *networkList;
        result = local_WlanGetAvailableNetworkList(handle, &interface.InterfaceGuid,
                                                   3, 0, &networkList);
        if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
            qDebug("%s: WlanGetAvailableNetworkList failed with error %ld\n",
                   __FUNCTION__, result);
#endif
            continue;
        }

        for (unsigned int j = 0; j < networkList->dwNumberOfItems; ++j) {
            WLAN_AVAILABLE_NETWORK &network = networkList->Network[j];

            profile = QString::fromWCharArray(network.strProfileName);

            if (qHash(QLatin1String("WLAN:") + profile) == id.toUInt())
                break;
            else
                profile.clear();
        }

        local_WlanFreeMemory(networkList);

        if (!profile.isEmpty()) {
            WLAN_CONNECTION_PARAMETERS parameters;
            parameters.wlanConnectionMode = wlan_connection_mode_profile;
            parameters.strProfile = reinterpret_cast<LPCWSTR>(profile.utf16());
            parameters.pDot11Ssid = 0;
            parameters.pDesiredBssidList = 0;
            parameters.dot11BssType = dot11_BSS_type_any;
            parameters.dwFlags = 0;

            DWORD result = local_WlanConnect(handle, &interface.InterfaceGuid, &parameters, 0);
            if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
                qDebug("%s: WlanConnect failed with error %ld\n", __FUNCTION__, result);
#endif
                locker.unlock();
                emit connectionError(id, ConnectError);
                locker.relock();
                break;
            }

            break;
        }
    }

    local_WlanFreeMemory(interfaceList);

    if (profile.isEmpty()) {
        locker.unlock();
        emit connectionError(id, InterfaceLookupError);
    }
}

void QNativeWifiEngine::disconnectFromId(const QString &id)
{
    QMutexLocker locker(&mutex);

    if (!available()) {
        locker.unlock();
        emit connectionError(id, InterfaceLookupError);
        return;
    }

    QString interface = getInterfaceFromId(id);

    if (interface.isEmpty()) {
        locker.unlock();
        emit connectionError(id, InterfaceLookupError);
        return;
    }

    const QVector<QStringRef> split = interface.midRef(1, interface.length() - 2).split(QLatin1Char('-'));

    GUID guid;
    guid.Data1 = split.at(0).toUInt(0, 16);
    guid.Data2 = split.at(1).toUShort(0, 16);
    guid.Data3 = split.at(2).toUShort(0, 16);
    guid.Data4[0] = split.at(3).left(2).toUShort(0, 16);
    guid.Data4[1] = split.at(3).right(2).toUShort(0, 16);
    for (int i = 0; i < 6; ++i)
        guid.Data4[i + 2] = split.at(4).mid(i*2, 2).toUShort(0, 16);

    DWORD result = local_WlanDisconnect(handle, &guid, 0);
    if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
        qDebug("%s: WlanDisconnect failed with error %ld\n", __FUNCTION__, result);
#endif
        locker.unlock();
        emit connectionError(id, DisconnectionError);
        return;
    }
}

void QNativeWifiEngine::initialize()
{
    scanComplete();
}

void QNativeWifiEngine::requestUpdate()
{
    QMutexLocker locker(&mutex);

    if (!available()) {
        locker.unlock();
        emit updateCompleted();
        return;
    }

    // enumerate interfaces
    WLAN_INTERFACE_INFO_LIST *interfaceList;
    DWORD result = local_WlanEnumInterfaces(handle, 0, &interfaceList);
    if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
        qDebug("%s: WlanEnumInterfaces failed with error %ld\n", __FUNCTION__, result);
#endif

        locker.unlock();
        emit updateCompleted();

        return;
    }

    bool requested = false;
    for (unsigned int i = 0; i < interfaceList->dwNumberOfItems; ++i) {
        result = local_WlanScan(handle, &interfaceList->InterfaceInfo[i].InterfaceGuid, 0, 0, 0);
        if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
            qDebug("%s: WlanScan failed with error %ld\n", __FUNCTION__, result);
#endif
        } else {
            requested = true;
        }
    }

    local_WlanFreeMemory(interfaceList);

    if (!requested) {
        locker.unlock();
        emit updateCompleted();
    }
}

QNetworkSession::State QNativeWifiEngine::sessionStateForId(const QString &id)
{
    QMutexLocker locker(&mutex);

    QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);

    if (!ptr)
        return QNetworkSession::Invalid;

    if (!ptr->isValid) {
        return QNetworkSession::Invalid;
    } else if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
        return QNetworkSession::Connected;
    } else if ((ptr->state & QNetworkConfiguration::Discovered) ==
                QNetworkConfiguration::Discovered) {
        return QNetworkSession::Disconnected;
    } else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
        return QNetworkSession::NotAvailable;
    } else if ((ptr->state & QNetworkConfiguration::Undefined) ==
                QNetworkConfiguration::Undefined) {
        return QNetworkSession::NotAvailable;
    }

    return QNetworkSession::Invalid;
}

QNetworkConfigurationManager::Capabilities QNativeWifiEngine::capabilities() const
{
    return QNetworkConfigurationManager::ForcedRoaming |
            QNetworkConfigurationManager::CanStartAndStopInterfaces;
}

QNetworkSessionPrivate *QNativeWifiEngine::createSessionBackend()
{
    return new QNetworkSessionPrivateImpl;
}

QNetworkConfigurationPrivatePointer QNativeWifiEngine::defaultConfiguration()
{
    return QNetworkConfigurationPrivatePointer();
}

bool QNativeWifiEngine::available()
{
    if (handle != INVALID_HANDLE_VALUE)
        return true;

    DWORD clientVersion;

    DWORD result = local_WlanOpenHandle(1, 0, &clientVersion, &handle);
    if (result != ERROR_SUCCESS) {
#ifdef BEARER_MANAGEMENT_DEBUG
        if (result != ERROR_SERVICE_NOT_ACTIVE)
            qDebug("%s: WlanOpenHandle failed with error %ld\n", __FUNCTION__, result);
#endif

        return false;
    }

    result = local_WlanRegisterNotification(handle, WLAN_NOTIFICATION_SOURCE_ALL, true,
                                            WLAN_NOTIFICATION_CALLBACK(qNotificationCallback),
                                            this, 0, 0);
#ifdef BEARER_MANAGEMENT_DEBUG
    if (result != ERROR_SUCCESS)
        qDebug("%s: WlanRegisterNotification failed with error %ld\n", __FUNCTION__, result);
#endif

    return handle != INVALID_HANDLE_VALUE;
}

void QNativeWifiEngine::closeHandle()
{
    if (handle != INVALID_HANDLE_VALUE) {
        local_WlanCloseHandle(handle, 0);
        handle = INVALID_HANDLE_VALUE;
    }
}

bool QNativeWifiEngine::requiresPolling() const
{
    // On Windows XP SP2 and SP3 only connection and disconnection notifications are available.
    // We need to poll for changes in available wireless networks.
    return QOperatingSystemVersion::current()
            <= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 5, 2);
}

QT_END_NAMESPACE

#endif // QT_NO_BEARERMANAGEMENT
