/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
** 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 "qdeclarativebluetoothdiscoverymodel_p.h"

#include <QPixmap>

#include <QtCore/QLoggingCategory>
#include <QtBluetooth/QBluetoothDeviceInfo>
#include <QtBluetooth/QBluetoothAddress>

#include "qdeclarativebluetoothservice_p.h"

/*!
    \qmltype BluetoothDiscoveryModel
    \instantiates QDeclarativeBluetoothDiscoveryModel
    \inqmlmodule QtBluetooth
    \since 5.2
    \brief Enables searching for the Bluetooth devices and services in
    range.

    BluetoothDiscoveryModel provides a model of connectable services. The
    contents of the model can be filtered by UUID allowing discovery to be
    limited to a single service such as a game.

    The model roles provided by BluetoothDiscoveryModel are
    \c service, \c name, \c remoteAddress and \c deviceName. The meaning of the roles
    changes based on the current \l discoveryMode.

    \table
        \header
            \li Model role
            \li Device Discovery
            \li Service Discovery
         \row
            \li \c name
            \li The device's name and address.
            \li The service name and the name of the device offering the service. If the device name is empty the devices address will be used.
         \row
            \li \c deviceName
            \li The name of the device.
            \li The name of the device offering the service.
         \row
            \li \c service
            \li The role is undefined in this mode.
            \li The \l BluetoothService object describing the discovered service.
         \row
            \li \c remoteAddress
            \li The address of the found device.
            \li The address of the device offering the service.
    \endtable

    \sa QBluetoothServiceDiscoveryAgent
*/

Q_DECLARE_LOGGING_CATEGORY(QT_BT_QML)

class QDeclarativeBluetoothDiscoveryModelPrivate
{
public:
    QDeclarativeBluetoothDiscoveryModelPrivate()
        :
        m_error(QDeclarativeBluetoothDiscoveryModel::NoError),
        m_discoveryMode(QDeclarativeBluetoothDiscoveryModel::MinimalServiceDiscovery),
        m_running(false),
        m_runningRequested(true),
        m_componentCompleted(false),
        m_currentState(QDeclarativeBluetoothDiscoveryModel::IdleAction),
        m_nextState(QDeclarativeBluetoothDiscoveryModel::IdleAction),
        m_wasDirectDeviceAgentCancel(false)
    {
    }
    ~QDeclarativeBluetoothDiscoveryModelPrivate()
    {
        if (m_deviceAgent)
            delete m_deviceAgent;

        if (m_serviceAgent)
            delete m_serviceAgent;

        qDeleteAll(m_services);
    }

    QBluetoothServiceDiscoveryAgent *m_serviceAgent = nullptr;
    QBluetoothDeviceDiscoveryAgent *m_deviceAgent = nullptr;

    QDeclarativeBluetoothDiscoveryModel::Error m_error;
    QList<QDeclarativeBluetoothService *> m_services;
    QList<QBluetoothDeviceInfo> m_devices;
    QDeclarativeBluetoothDiscoveryModel::DiscoveryMode m_discoveryMode;
    QString m_uuid;
    bool m_running;
    bool m_runningRequested;
    bool m_componentCompleted;
    QString m_remoteAddress;

    QDeclarativeBluetoothDiscoveryModel::Action m_currentState;
    QDeclarativeBluetoothDiscoveryModel::Action m_nextState;
    bool m_wasDirectDeviceAgentCancel;
};

QDeclarativeBluetoothDiscoveryModel::QDeclarativeBluetoothDiscoveryModel(QObject *parent) :
    QAbstractListModel(parent),
    d(new QDeclarativeBluetoothDiscoveryModelPrivate)
{
    d->m_deviceAgent = new QBluetoothDeviceDiscoveryAgent(this);
    connect(d->m_deviceAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered,
            this, QOverload<const QBluetoothDeviceInfo&>::of(&QDeclarativeBluetoothDiscoveryModel::deviceDiscovered));
    connect(d->m_deviceAgent, &QBluetoothDeviceDiscoveryAgent::finished,
            this, &QDeclarativeBluetoothDiscoveryModel::finishedDiscovery);
    connect(d->m_deviceAgent, &QBluetoothDeviceDiscoveryAgent::canceled,
            this, &QDeclarativeBluetoothDiscoveryModel::finishedDiscovery);
    connect(d->m_deviceAgent,
            QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(&QBluetoothDeviceDiscoveryAgent::error),
            this,
            &QDeclarativeBluetoothDiscoveryModel::errorDeviceDiscovery);
    d->m_deviceAgent->setObjectName(QStringLiteral("DeviceDiscoveryAgent"));

    d->m_serviceAgent = new QBluetoothServiceDiscoveryAgent(this);
    connect(d->m_serviceAgent, &QBluetoothServiceDiscoveryAgent::serviceDiscovered,
            this, QOverload<const QBluetoothServiceInfo&>::of(&QDeclarativeBluetoothDiscoveryModel::serviceDiscovered));
    connect(d->m_serviceAgent, &QBluetoothServiceDiscoveryAgent::finished,
            this, &QDeclarativeBluetoothDiscoveryModel::finishedDiscovery);
    connect(d->m_serviceAgent, &QBluetoothServiceDiscoveryAgent::canceled,
            this, &QDeclarativeBluetoothDiscoveryModel::finishedDiscovery);
    connect(d->m_serviceAgent,
            QOverload<QBluetoothServiceDiscoveryAgent::Error>::of(&QBluetoothServiceDiscoveryAgent::error),
            this,
            &QDeclarativeBluetoothDiscoveryModel::errorDiscovery);
    d->m_serviceAgent->setObjectName(QStringLiteral("ServiceDiscoveryAgent"));
}

QDeclarativeBluetoothDiscoveryModel::~QDeclarativeBluetoothDiscoveryModel()
{
    delete d;
}
void QDeclarativeBluetoothDiscoveryModel::componentComplete()
{
    d->m_componentCompleted = true;
    if (d->m_runningRequested)
        setRunning(true);
}

void QDeclarativeBluetoothDiscoveryModel::errorDiscovery(QBluetoothServiceDiscoveryAgent::Error error)
{
    switch (error) {
    case QBluetoothServiceDiscoveryAgent::InvalidBluetoothAdapterError:
        d->m_error = QDeclarativeBluetoothDiscoveryModel::InvalidBluetoothAdapterError; break;
    case QBluetoothServiceDiscoveryAgent::NoError:
        d->m_error = QDeclarativeBluetoothDiscoveryModel::NoError; break;
    case QBluetoothServiceDiscoveryAgent::InputOutputError:
        d->m_error = QDeclarativeBluetoothDiscoveryModel::InputOutputError; break;
    case QBluetoothServiceDiscoveryAgent::PoweredOffError:
        d->m_error = QDeclarativeBluetoothDiscoveryModel::PoweredOffError; break;
    case QBluetoothServiceDiscoveryAgent::UnknownError:
        d->m_error = QDeclarativeBluetoothDiscoveryModel::UnknownError; break;
    }

    emit errorChanged();
}

void QDeclarativeBluetoothDiscoveryModel::errorDeviceDiscovery(QBluetoothDeviceDiscoveryAgent::Error error)
{
    d->m_error = static_cast<QDeclarativeBluetoothDiscoveryModel::Error>(error);
    emit errorChanged();

    //QBluetoothDeviceDiscoveryAgent::finished() signal is not emitted in case of an error
    //Note that this behavior is different from QBluetoothServiceDiscoveryAgent.
    //This resets the models running flag.
    finishedDiscovery();
}

void QDeclarativeBluetoothDiscoveryModel::clearModel()
{
    beginResetModel();
    qDeleteAll(d->m_services);
    d->m_services.clear();
    d->m_devices.clear();
    endResetModel();
}

/*!
    \qmlproperty enumeration BluetoothDiscoveryModel::error

    This property holds the last error reported during discovery.
    \table
    \header \li Property \li Description
    \row \li \c BluetoothDiscoveryModel.NoError
         \li No error occurred.
    \row \li \c BluetoothDiscoveryModel.InputOutputError
         \li An IO failure occurred during device discovery
    \row \li \c BluetoothDiscoveryModel.PoweredOffError
         \li The bluetooth device is not powered on.
    \row \li \c BluetoothDiscoveryModel.InvalidBluetoothAdapterError
         \li There is no default Bluetooth device to perform the
             service discovery. The model always uses the local default adapter.
             Specifying a default adapter is not possible. If that's required,
             \l QBluetoothServiceDiscoveryAgent should be directly used. This
             value was introduced by Qt 5.4.
    \row \li \c BluetoothDiscoveryModel.UnknownError
         \li An unknown error occurred.
    \endtable

  This property is read-only.
  */
QDeclarativeBluetoothDiscoveryModel::Error QDeclarativeBluetoothDiscoveryModel::error() const
{
    return d->m_error;
}

int QDeclarativeBluetoothDiscoveryModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    if (discoveryMode() == DeviceDiscovery)
        return d->m_devices.count();
    else
        return d->m_services.count();
}

QVariant QDeclarativeBluetoothDiscoveryModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() < 0)
        return QVariant();

    if (discoveryMode() != DeviceDiscovery) {
        if (index.row() >= d->m_services.count()){
            qCWarning(QT_BT_QML) << "index out of bounds";
            return QVariant();
        }

        QDeclarativeBluetoothService *service = d->m_services.value(index.row());

        switch (role) {
            case Name: {
                QString label = service->deviceName();
                if (label.isEmpty())
                    label += service->deviceAddress();
                else
                    label+= QStringLiteral(":");
                label += QStringLiteral(" ") + service->serviceName();
                return label;
            }
            case ServiceRole:
                return QVariant::fromValue(service);
            case DeviceName:
                return service->deviceName();
            case RemoteAddress:
                return service->deviceAddress();
        }
    } else {
        if (index.row() >= d->m_devices.count()) {
            qCWarning(QT_BT_QML) << "index out of bounds";
            return QVariant();
        }

        QBluetoothDeviceInfo device = d->m_devices.value(index.row());
        switch (role) {
            case Name:
            return (device.name() + QStringLiteral(" (") + device.address().toString() + QStringLiteral(")"));
            case ServiceRole:
                break;
            case DeviceName:
                return device.name();
            case RemoteAddress:
                return device.address().toString();
        }
    }

    return QVariant();
}

QHash<int,QByteArray> QDeclarativeBluetoothDiscoveryModel::roleNames() const
{
    return {{Name, "name"},
            {ServiceRole, "service"},
            {RemoteAddress, "remoteAddress"},
            {DeviceName, "deviceName"}};
}

/*!
  \qmlsignal BluetoothDiscoveryModel::serviceDiscovered(BluetoothService service)

  This signal is emitted when a new service is discovered. The \a service
  parameter contains the service details.

  The corresponding handler is \c onServiceDiscovered.

  \sa BluetoothService
  */

void QDeclarativeBluetoothDiscoveryModel::serviceDiscovered(const QBluetoothServiceInfo &service)
{
    //qDebug() << "service discovered";

    QDeclarativeBluetoothService *bs = new QDeclarativeBluetoothService(service, this);
    QDeclarativeBluetoothService *current = nullptr;
    for (int i = 0; i < d->m_services.count(); i++) {
        current = d->m_services.at(i);
        if (bs->deviceAddress() == current->deviceAddress()
                && bs->serviceName() == current->serviceName()
                && bs->serviceUuid() == current->serviceUuid()) {
            delete bs;
            return;
        }
    }

    beginInsertRows(QModelIndex(),d->m_services.count(), d->m_services.count());
    d->m_services.append(bs);
    endInsertRows();
    emit serviceDiscovered(bs);
}

/*!
  \qmlsignal BluetoothDiscoveryModel::deviceDiscovered(string device)

  This signal is emitted when a new device is discovered. \a device contains
  the Bluetooth address of the discovered device.

  The corresponding handler is \c onDeviceDiscovered.
  */

void QDeclarativeBluetoothDiscoveryModel::deviceDiscovered(const QBluetoothDeviceInfo &device)
{
    //qDebug() << "Device discovered" << device.address().toString() << device.name();

    beginInsertRows(QModelIndex(),d->m_devices.count(), d->m_devices.count());
    d->m_devices.append(device);
    endInsertRows();
    emit deviceDiscovered(device.address().toString());
}

void QDeclarativeBluetoothDiscoveryModel::finishedDiscovery()
{
    QDeclarativeBluetoothDiscoveryModel::Action previous = d->m_currentState;
    d->m_currentState = IdleAction;

    switch (previous) {
    case IdleAction:
        // last transition didn't even start
        // can happen when start() or stop() immediately returned
        // usually this happens within a current transitionToNextAction call
        break;
    case StopAction:
        qCDebug(QT_BT_QML) << "Agent cancel detected";
        transitionToNextAction();
        break;
    default: // all other
        qCDebug(QT_BT_QML) << "Discovery finished" << sender()->objectName();

        //TODO Qt6 This hack below is once again due to the pendingCancel logic
        //         because QBluetoothDeviceDiscoveryAgent::isActive() is not reliable.
        //         In toggleStartStop() we need to know whether the stop() is delayed or immediate.
        //         isActive() cannot be used. Hence we have to wait for the canceled() signal.
        //         Android, WinRT and Bluez5 are immediate, Bluez4 is always delayed.
        //         The immediate case is what we catch here.
        if (sender() == d->m_deviceAgent && d->m_nextState == StopAction) {
            d->m_wasDirectDeviceAgentCancel = true;
            return;
        }
        setRunning(false);
        break;
    }
}

/*!
    \qmlproperty enumeration BluetoothDiscoveryModel::discoveryMode

    Sets the discovery mode. The discovery mode has to be set before the discovery is started
    \table
    \header \li Property \li Description
    \row \li \c BluetoothDiscoveryModel.FullServiceDiscovery
         \li Starts a full discovery of all services of all devices in range.
    \row \li \c BluetoothDiscoveryModel.MinimalServiceDiscovery
         \li (Default) Starts a minimal discovery of all services of all devices in range. A minimal discovery is
         faster but only guarantees the device and UUID information to be correct.
    \row \li \c BluetoothDiscoveryModel.DeviceDiscovery
         \li Discovers only devices in range. The service role will be 0 for any model item.
    \endtable
*/

QDeclarativeBluetoothDiscoveryModel::DiscoveryMode QDeclarativeBluetoothDiscoveryModel::discoveryMode() const
{
    return d->m_discoveryMode;
}

void QDeclarativeBluetoothDiscoveryModel::setDiscoveryMode(DiscoveryMode discovery)
{
    d->m_discoveryMode = discovery;
    emit discoveryModeChanged();
}


void QDeclarativeBluetoothDiscoveryModel::updateNextAction(Action action)
{
    qCDebug(QT_BT_QML) << "New action queue:"
                       << d->m_currentState << d->m_nextState << action;

    if (action == IdleAction)
        return;

    switch (d->m_nextState) {
    case IdleAction:
        d->m_nextState = action;
        return;
    case StopAction:
        qWarning() << "Invalid Stop state when processing new action" << action;
        return;
    case DeviceDiscoveryAction:
    case MinimalServiceDiscoveryAction:
    case FullServiceDiscoveryAction:
        if (action == StopAction) // cancel out previous start call
            d->m_nextState = IdleAction;
        else
            qWarning() << "Ignoring new DMF state while another DMF state is scheduled.";
        return;
    }
}

void QDeclarativeBluetoothDiscoveryModel::transitionToNextAction()
{
    qCDebug(QT_BT_QML) << "Before transition change:" << d->m_currentState << d->m_nextState;
    bool isRunning;
    switch (d->m_currentState) {
    case IdleAction:
        switch (d->m_nextState) {
        case IdleAction: break; // nothing to do
        case StopAction: d->m_nextState = IdleAction; break; // clear, nothing to do
        case DeviceDiscoveryAction:
        case MinimalServiceDiscoveryAction:
        case FullServiceDiscoveryAction:
            Action temp = d->m_nextState;
            clearModel();
            isRunning = toggleStartStop(d->m_nextState);
            d->m_nextState = IdleAction;
            if (isRunning) {
                d->m_currentState = temp;
            } else {
                if (temp != DeviceDiscoveryAction )
                    errorDiscovery(d->m_serviceAgent->error());
                d->m_running = false;
            }
        }
        break;
    case StopAction:
        break; // do nothing, StopAction cleared by finished()/cancelled()/error() handlers
    case DeviceDiscoveryAction:
    case MinimalServiceDiscoveryAction:
    case FullServiceDiscoveryAction:
        switch (d->m_nextState) {
        case IdleAction: break;
        case StopAction:
            isRunning = toggleStartStop(StopAction);
            (isRunning) ? d->m_currentState = StopAction : d->m_currentState = IdleAction;
            d->m_nextState = IdleAction;
            break;
         default:
            Q_ASSERT(false); // should never happen
            break;
        }

        break;
    }

    qCDebug(QT_BT_QML) << "After transition change:" << d->m_currentState << d->m_nextState;
}

// Returns true if the agent is active
// this can be used to detect whether the agent still needs time to
// perform the requested action.
bool QDeclarativeBluetoothDiscoveryModel::toggleStartStop(Action action)
{
    Q_ASSERT(action != IdleAction);
    switch (action) {
    case DeviceDiscoveryAction:
        Q_ASSERT(!d->m_deviceAgent->isActive() && !d->m_serviceAgent->isActive());
        d->m_deviceAgent->start();
        return d->m_deviceAgent->isActive();
    case MinimalServiceDiscoveryAction:
    case FullServiceDiscoveryAction:
        Q_ASSERT(!d->m_deviceAgent->isActive() && !d->m_serviceAgent->isActive());
        d->m_serviceAgent->setRemoteAddress(QBluetoothAddress(d->m_remoteAddress));
        d->m_serviceAgent->clear();

        if (!d->m_uuid.isEmpty())
            d->m_serviceAgent->setUuidFilter(QBluetoothUuid(d->m_uuid));

        if (action == FullServiceDiscoveryAction)  {
            qCDebug(QT_BT_QML) << "Full Discovery";
            d->m_serviceAgent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
        } else {
            qCDebug(QT_BT_QML) << "Minimal Discovery";
            d->m_serviceAgent->start(QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
        }
        return d->m_serviceAgent->isActive();
    case StopAction:
        Q_ASSERT(d->m_currentState != StopAction && d->m_currentState != IdleAction);
        if (d->m_currentState == DeviceDiscoveryAction) {
            d->m_deviceAgent->stop();

            // TODO Qt6 Crude hack below
            // cannot use isActive() below due to pendingCancel logic
            // we always wait for canceled() signal coming through or check
            // for directly invoked cancel() response caused by stop() above
            bool stillActive = !d->m_wasDirectDeviceAgentCancel;
            d->m_wasDirectDeviceAgentCancel = false;
            return stillActive;
        } else {
            d->m_serviceAgent->stop();
            return d->m_serviceAgent->isActive();
        }
    default:
        return true;
    }
}


/*!
  \qmlproperty bool BluetoothDiscoveryModel::running

  This property starts or stops discovery. A restart of the discovery process
  requires setting this property to \c false and subsequently to \c true again.

*/

bool QDeclarativeBluetoothDiscoveryModel::running() const
{
    return d->m_running;
}

void QDeclarativeBluetoothDiscoveryModel::setRunning(bool running)
{
    if (!d->m_componentCompleted) {
        d->m_runningRequested = running;
        return;
    }

    if (d->m_running == running)
        return;

    d->m_running = running;

    Action nextAction = IdleAction;
    if (running) {
        if (discoveryMode() == MinimalServiceDiscovery)
            nextAction = MinimalServiceDiscoveryAction;
        else if (discoveryMode() == FullServiceDiscovery)
            nextAction = FullServiceDiscoveryAction;
        else
            nextAction = DeviceDiscoveryAction;
    } else {
        nextAction = StopAction;
    }

    Q_ASSERT(nextAction != IdleAction);
    updateNextAction(nextAction);
    transitionToNextAction();

    qCDebug(QT_BT_QML) << "Running state:" << d->m_running;
    emit runningChanged();
}

/*!
  \qmlproperty string BluetoothDiscoveryModel::uuidFilter

  This property holds an optional UUID filter.  A UUID can be used to return only
  matching services.  16 bit, 32 bit or 128 bit UUIDs can be used.  The string format
  is same as the format of QUuid.

  \sa QBluetoothUuid
  \sa QUuid
  */


QString QDeclarativeBluetoothDiscoveryModel::uuidFilter() const
{
    return d->m_uuid;
}

void QDeclarativeBluetoothDiscoveryModel::setUuidFilter(QString uuid)
{
    if (uuid == d->m_uuid)
        return;

    QBluetoothUuid qbuuid(uuid);
    if (qbuuid.isNull()) {
        qCWarning(QT_BT_QML) << "Invalid UUID providded " << uuid;
        return;
    }
    d->m_uuid = uuid;
    emit uuidFilterChanged();
}

/*!
    \qmlproperty string BluetoothDiscoveryModel::remoteAddress

    This property holds an optional bluetooth address for a remote bluetooth device.
    Only services on this remote device will be discovered. It has no effect if
    an invalid bluetooth address was set or if the property was set after the discovery
    was started.

    The property is ignored if device discovery is selected.

*/

QString QDeclarativeBluetoothDiscoveryModel::remoteAddress()
{
    return d->m_remoteAddress;
}

void QDeclarativeBluetoothDiscoveryModel::setRemoteAddress(QString address)
{
    d->m_remoteAddress = address;
    emit remoteAddressChanged();
}
