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

#include "osx/osxbtledeviceinquiry_p.h"
#ifdef Q_OS_MACOS
#include "osx/osxbtdeviceinquiry_p.h"
#include "osx/osxbtsdpinquiry_p.h"
#endif // Q_OS_MACOS
#include "qbluetoothdeviceinfo.h"
#include "osx/osxbtnotifier_p.h"
#include "osx/osxbtutility_p.h"
#include "osx/osxbluetooth_p.h"
#include "osx/uistrings_p.h"
#include "qbluetoothhostinfo.h"
#include "qbluetoothaddress.h"
#include "osx/uistrings_p.h"
#include "qbluetoothuuid.h"
#include "osx/btraii_p.h"

#include <QtCore/qloggingcategory.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qvector.h>
#include <QtCore/qglobal.h>
#include <QtCore/qstring.h>
#include <QtCore/qdebug.h>

#include <Foundation/Foundation.h>

QT_BEGIN_NAMESPACE

namespace
{

void registerQDeviceDiscoveryMetaType()
{
    static bool initDone = false;
    if (!initDone) {
        qRegisterMetaType<QBluetoothDeviceInfo>();
        qRegisterMetaType<QBluetoothDeviceDiscoveryAgent::Error>();
        initDone = true;
    }
}
#ifdef Q_OS_MACOS
using InquiryObjC = QT_MANGLE_NAMESPACE(OSXBTDeviceInquiry);
#endif // Q_OS_MACOS

using LEInquiryObjC = QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry);

} //namespace

QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(const QBluetoothAddress &adapter,
                                                                             QBluetoothDeviceDiscoveryAgent *q) :
    inquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry),
    lastError(QBluetoothDeviceDiscoveryAgent::NoError),
    agentState(NonActive),
    adapterAddress(adapter),
    startPending(false),
    stopPending(false),
    lowEnergySearchTimeout(OSXBluetooth::defaultLEScanTimeoutMS),
#ifdef Q_OS_MACOS
    requestedMethods(QBluetoothDeviceDiscoveryAgent::ClassicMethod | QBluetoothDeviceDiscoveryAgent::LowEnergyMethod),
#else
    requestedMethods(QBluetoothDeviceDiscoveryAgent::ClassicMethod),
#endif // Q_OS_MACOS
    q_ptr(q)
{
    registerQDeviceDiscoveryMetaType();

    Q_ASSERT_X(q != nullptr, Q_FUNC_INFO, "invalid q_ptr (null)");

#ifdef Q_OS_MACOS
    IOBluetoothHostController *hostController = [IOBluetoothHostController defaultController];
    if (!hostController || [hostController powerState] != kBluetoothHCIPowerStateON) {
        qCCritical(QT_BT_OSX) << "no default host controller or adapter is off";
        return;
    }
    controller.reset(hostController, DarwinBluetooth::RetainPolicy::doInitialRetain);
#endif
}

QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate()
{
    if (inquiryLE && agentState != NonActive) {
        // We want the LE scan to stop as soon as possible.
        if (dispatch_queue_t leQueue = OSXBluetooth::qt_LE_queue()) {
            // Local variable to be retained ...
            LEInquiryObjC *inq = inquiryLE.getAs<LEInquiryObjC>();
            dispatch_sync(leQueue, ^{
                [inq stop];
            });
        }
    }
}

bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const
{
    if (startPending)
        return true;

    if (stopPending)
        return false;

    return agentState != NonActive;
}

void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods)
{
    Q_ASSERT(!isActive());
    Q_ASSERT(lastError != QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError);
    Q_ASSERT(methods & (QBluetoothDeviceDiscoveryAgent::ClassicMethod
                        | QBluetoothDeviceDiscoveryAgent::LowEnergyMethod));

#ifdef Q_OS_MACOS
    if (!controller) {
        setError(QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError);
        emit q_ptr->error(lastError);
        return;
    }
#endif // Q_OS_MACOS

    requestedMethods = methods;

    if (stopPending) {
        startPending = true;
        return;
    }

    // This function (re)starts the scan(s) from the scratch;
    // starting from Classic if it's in 'methods' (or LE scan if not).

    agentState = NonActive;
    discoveredDevices.clear();
    setError(QBluetoothDeviceDiscoveryAgent::NoError);
#ifdef Q_OS_MACOS
    if (requestedMethods & QBluetoothDeviceDiscoveryAgent::ClassicMethod)
        return startClassic();
#endif // Q_OS_MACOS

    startLE();
}

#ifdef Q_OS_MACOS

void QBluetoothDeviceDiscoveryAgentPrivate::startClassic()
{
    Q_ASSERT(!isActive());
    Q_ASSERT(lastError == QBluetoothDeviceDiscoveryAgent::NoError);
    Q_ASSERT(requestedMethods & QBluetoothDeviceDiscoveryAgent::ClassicMethod);
    Q_ASSERT(agentState == NonActive);

    OSXBluetooth::qt_test_iobluetooth_runloop();

    if (!inquiry) {
        // The first Classic scan for this DDA.
        inquiry.reset([[InquiryObjC alloc] initWithDelegate:this],
                      DarwinBluetooth::RetainPolicy::noInitialRetain);

        if (!inquiry) {
            qCCritical(QT_BT_OSX) << "failed to initialize an Classic device inquiry";
            setError(QBluetoothDeviceDiscoveryAgent::UnknownError,
                     QCoreApplication::translate(DEV_DISCOVERY, DD_NOT_STARTED));
            emit q_ptr->error(lastError);
            return;
        }
    }

    agentState = ClassicScan;

    const IOReturn res = [inquiry.getAs<InquiryObjC>() start];
    if (res != kIOReturnSuccess) {
        setError(res, QCoreApplication::translate(DEV_DISCOVERY, DD_NOT_STARTED));
        agentState = NonActive;
        emit q_ptr->error(lastError);
    }
}

#endif // Q_OS_MACOS

void QBluetoothDeviceDiscoveryAgentPrivate::startLE()
{
    Q_ASSERT(lastError != QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError);
    Q_ASSERT(requestedMethods & QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);

    using namespace OSXBluetooth;

    QScopedPointer<LECBManagerNotifier> notifier(new LECBManagerNotifier);
    // Connections:
    using ErrMemFunPtr = void (LECBManagerNotifier::*)(QBluetoothDeviceDiscoveryAgent::Error);
    notifier->connect(notifier.data(), ErrMemFunPtr(&LECBManagerNotifier::CBManagerError),
                      this, &QBluetoothDeviceDiscoveryAgentPrivate::LEinquiryError);
    notifier->connect(notifier.data(), &LECBManagerNotifier::LEnotSupported,
                      this, &QBluetoothDeviceDiscoveryAgentPrivate::LEnotSupported);
    notifier->connect(notifier.data(), &LECBManagerNotifier::discoveryFinished,
                      this, &QBluetoothDeviceDiscoveryAgentPrivate::LEinquiryFinished);
    using DeviceMemFunPtr = void (QBluetoothDeviceDiscoveryAgentPrivate::*)(const QBluetoothDeviceInfo &);
    notifier->connect(notifier.data(), &LECBManagerNotifier::deviceDiscovered,
                      this, DeviceMemFunPtr(&QBluetoothDeviceDiscoveryAgentPrivate::deviceFound));

    // Check queue and create scanner:
    inquiryLE.reset([[LEInquiryObjC alloc] initWithNotifier:notifier.data()],
                    DarwinBluetooth::RetainPolicy::noInitialRetain);
    if (inquiryLE)
        notifier.take(); // Whatever happens next, inquiryLE is already the owner ...

    dispatch_queue_t leQueue(qt_LE_queue());
    if (!leQueue || !inquiryLE) {
        setError(QBluetoothDeviceDiscoveryAgent::UnknownError,
                 QCoreApplication::translate(DEV_DISCOVERY, DD_NOT_STARTED_LE));
        agentState = NonActive;
        emit q_ptr->error(lastError);
        return;
    }

    // Now start in on LE queue:
    agentState = LEScan;
    // We need the local variable so that it's retained ...
    LEInquiryObjC *inq = inquiryLE.getAs<LEInquiryObjC>();
    dispatch_async(leQueue, ^{
        [inq startWithTimeout:lowEnergySearchTimeout];
    });
}

void QBluetoothDeviceDiscoveryAgentPrivate::stop()
{
    Q_ASSERT_X(isActive(), Q_FUNC_INFO, "called whithout active inquiry");
    Q_ASSERT_X(lastError != QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError,
               Q_FUNC_INFO, "called with invalid bluetooth adapter");

    using namespace OSXBluetooth;

    const bool prevStart = startPending;
    startPending = false;
    stopPending = true;

    setError(QBluetoothDeviceDiscoveryAgent::NoError);

#ifdef Q_OS_MACOS
    if (agentState == ClassicScan) {
        const IOReturn res = [inquiry.getAs<InquiryObjC>() stop];
        if (res != kIOReturnSuccess) {
            qCWarning(QT_BT_OSX) << "failed to stop";
            startPending = prevStart;
            stopPending = false;
            setError(res, QCoreApplication::translate(DEV_DISCOVERY, DD_NOT_STOPPED));
            emit q_ptr->error(lastError);
        }
    } else {
#else
    {
        Q_UNUSED(prevStart)
#endif // Q_OS_MACOS
        dispatch_queue_t leQueue(qt_LE_queue());
        Q_ASSERT(leQueue);
        // We need the local variable so that it's retained ...
        LEInquiryObjC *inq = inquiryLE.getAs<LEInquiryObjC>();
        dispatch_sync(leQueue, ^{
            [inq stop];
        });
        // We consider LE scan to be stopped immediately and
        // do not care about this LEDeviceInquiry object anymore.
        LEinquiryFinished();
    }
}

#ifdef Q_OS_MACOS

void QBluetoothDeviceDiscoveryAgentPrivate::inquiryFinished()
{
    // The subsequent start(LE) function (if any)
    // will (re)set the correct state.
    agentState = NonActive;

    if (stopPending && !startPending) {
        stopPending = false;
        emit q_ptr->canceled();
    } else if (startPending) {
        startPending = false;
        stopPending = false;
        start(requestedMethods);
    } else {
        // We can be here _only_ if a classic scan
        // finished in a normal way (not cancelled)
        // and requestedMethods includes LowEnergyMethod.
        // startLE() will take care of old devices
        // not supporting Bluetooth 4.0.
        if (requestedMethods & QBluetoothDeviceDiscoveryAgent::LowEnergyMethod)
            startLE();
        else
            emit q_ptr->finished();
    }
}

void QBluetoothDeviceDiscoveryAgentPrivate::error(IOReturn error)
{
    startPending = false;
    stopPending = false;

    setError(error);

    emit q_ptr->error(lastError);
}

void QBluetoothDeviceDiscoveryAgentPrivate::classicDeviceFound(void *obj)
{
    auto device = static_cast<IOBluetoothDevice *>(obj);
    Q_ASSERT_X(device, Q_FUNC_INFO, "invalid IOBluetoothDevice (nil)");

    Q_ASSERT_X(agentState == ClassicScan, Q_FUNC_INFO,
               "invalid agent state (expected classic scan)");

    QT_BT_MAC_AUTORELEASEPOOL;

    // Let's collect some info about this device:
    const QBluetoothAddress deviceAddress(OSXBluetooth::qt_address([device getAddress]));
    if (deviceAddress.isNull()) {
        qCWarning(QT_BT_OSX) << "invalid Bluetooth address";
        return;
    }

    QString deviceName;
    if (device.name)
        deviceName = QString::fromNSString(device.name);

    const auto classOfDevice = qint32(device.classOfDevice);

    QBluetoothDeviceInfo deviceInfo(deviceAddress, deviceName, classOfDevice);
    deviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::BaseRateCoreConfiguration);
    deviceInfo.setRssi(device.RSSI);

    const QVector<QBluetoothUuid> uuids(OSXBluetooth::extract_services_uuids(device));
    deviceInfo.setServiceUuids(uuids);

    deviceFound(deviceInfo);
}

void QBluetoothDeviceDiscoveryAgentPrivate::setError(IOReturn error, const QString &text)
{
    if (error == kIOReturnSuccess)
        setError(QBluetoothDeviceDiscoveryAgent::NoError, text);
    else if (error == kIOReturnNoPower)
        setError(QBluetoothDeviceDiscoveryAgent::PoweredOffError, text);
    else
        setError(QBluetoothDeviceDiscoveryAgent::UnknownError, text);
}

#endif // Q_OS_MACOS

void QBluetoothDeviceDiscoveryAgentPrivate::setError(QBluetoothDeviceDiscoveryAgent::Error error, const QString &text)
{
    lastError = error;

    if (text.length() > 0) {
        errorString = text;
    } else {
        switch (lastError) {
        case QBluetoothDeviceDiscoveryAgent::NoError:
            errorString = QString();
            break;
        case QBluetoothDeviceDiscoveryAgent::PoweredOffError:
            errorString = QCoreApplication::translate(DEV_DISCOVERY, DD_POWERED_OFF);
            break;
        case QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError:
            errorString = QCoreApplication::translate(DEV_DISCOVERY, DD_INVALID_ADAPTER);
            break;
        case QBluetoothDeviceDiscoveryAgent::InputOutputError:
            errorString = QCoreApplication::translate(DEV_DISCOVERY, DD_IO);
            break;
        case QBluetoothDeviceDiscoveryAgent::UnsupportedPlatformError:
            errorString = QCoreApplication::translate(DEV_DISCOVERY, DD_NOTSUPPORTED);
            break;
        case QBluetoothDeviceDiscoveryAgent::UnknownError:
        default:
            errorString = QCoreApplication::translate(DEV_DISCOVERY, DD_UNKNOWN_ERROR);
        }
    }
}

void QBluetoothDeviceDiscoveryAgentPrivate::LEinquiryError(QBluetoothDeviceDiscoveryAgent::Error error)
{
    Q_ASSERT(error == QBluetoothDeviceDiscoveryAgent::PoweredOffError
             || error == QBluetoothDeviceDiscoveryAgent::UnsupportedDiscoveryMethod);

    inquiryLE.reset();

    startPending = false;
    stopPending = false;
    agentState = NonActive;
    setError(error);
    emit q_ptr->error(lastError);
}

void QBluetoothDeviceDiscoveryAgentPrivate::LEnotSupported()
{
    qCDebug(QT_BT_OSX) << "no Bluetooth LE support";

#ifdef Q_OS_MACOS
    if (requestedMethods & QBluetoothDeviceDiscoveryAgent::ClassicMethod) {
        // Having both Classic | LE means this is not an error.
        LEinquiryFinished();
    } else {
        // In the past this was never an error, that's why we have
        // LEnotSupported as a special method. But now, since
        // we can have separate Classic/LE scans, we have to report it
        // as UnsupportedDiscoveryMethod.
        LEinquiryError(QBluetoothDeviceDiscoveryAgent::UnsupportedDiscoveryMethod);
    }
#else
    inquiryLE.reset();
    startPending = false;
    stopPending = false;
    setError(QBluetoothDeviceDiscoveryAgent::UnsupportedPlatformError);
    emit q_ptr->error(lastError);
#endif
}

void QBluetoothDeviceDiscoveryAgentPrivate::LEinquiryFinished()
{
    // The same logic as in inquiryFinished, but does not start LE scan.
    agentState = NonActive;
    inquiryLE.reset();

    if (stopPending && !startPending) {
        stopPending = false;
        emit q_ptr->canceled();
    } else if (startPending) {
        startPending = false;
        stopPending = false;
        start(requestedMethods); //Start again.
    } else {
        emit q_ptr->finished();
    }
}

void QBluetoothDeviceDiscoveryAgentPrivate::deviceFound(const QBluetoothDeviceInfo &newDeviceInfo)
{
    // Core Bluetooth does not allow us to access addresses, we have to use uuid instead.
    // This uuid has nothing to do with uuids in Bluetooth in general (it's generated by
    // Apple's framework using some algorithm), but it's a 128-bit uuid after all.
    const bool isLE =
#ifdef Q_OS_MACOS
            newDeviceInfo.coreConfigurations() == QBluetoothDeviceInfo::LowEnergyCoreConfiguration;
#else
            true;
#endif // Q_OS_MACOS
    for (int i = 0, e = discoveredDevices.size(); i < e; ++i) {
        if (isLE) {
            if (discoveredDevices[i].deviceUuid() == newDeviceInfo.deviceUuid()) {
                QBluetoothDeviceInfo::Fields updatedFields = QBluetoothDeviceInfo::Field::None;
                if (discoveredDevices[i].rssi() != newDeviceInfo.rssi()) {
                    qCDebug(QT_BT_OSX) << "Updating RSSI for" << newDeviceInfo.address()
                                       << newDeviceInfo.rssi();
                    discoveredDevices[i].setRssi(newDeviceInfo.rssi());
                    updatedFields.setFlag(QBluetoothDeviceInfo::Field::RSSI);
                }

                if (discoveredDevices[i].manufacturerData() != newDeviceInfo.manufacturerData()) {
                    qCDebug(QT_BT_OSX) << "Updating manufacturer data for" << newDeviceInfo.address();
                    const QVector<quint16> keys = newDeviceInfo.manufacturerIds();
                    for (auto key: keys)
                        discoveredDevices[i].setManufacturerData(key, newDeviceInfo.manufacturerData(key));
                    updatedFields.setFlag(QBluetoothDeviceInfo::Field::ManufacturerData);
                }

                if (lowEnergySearchTimeout > 0) {
                    if (discoveredDevices[i] != newDeviceInfo) {
                        discoveredDevices.replace(i, newDeviceInfo);
                        emit q_ptr->deviceDiscovered(newDeviceInfo);
                    } else {
                        if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None))
                            emit q_ptr->deviceUpdated(discoveredDevices[i], updatedFields);
                    }

                    return;
                }

                discoveredDevices.replace(i, newDeviceInfo);
                emit q_ptr->deviceDiscovered(newDeviceInfo);

                if (!updatedFields.testFlag(QBluetoothDeviceInfo::Field::None))
                    emit q_ptr->deviceUpdated(discoveredDevices[i], updatedFields);

                return;
            }
        } else {
#ifdef Q_OS_MACOS
            if (discoveredDevices[i].address() == newDeviceInfo.address()) {
                if (discoveredDevices[i] == newDeviceInfo)
                    return;

                discoveredDevices.replace(i, newDeviceInfo);
                emit q_ptr->deviceDiscovered(newDeviceInfo);
                return;
            }
#else
            Q_UNREACHABLE();
#endif // Q_OS_MACOS
        }
    }

    discoveredDevices.append(newDeviceInfo);
    emit q_ptr->deviceDiscovered(newDeviceInfo);
}

QBluetoothDeviceDiscoveryAgent::DiscoveryMethods QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods()
{
#ifdef Q_OS_MACOS
    return ClassicMethod | LowEnergyMethod;
#else
    return LowEnergyMethod;
#endif // Q_OS_MACOS
}

QT_END_NAMESPACE
