/****************************************************************************
**
** Copyright (C) 2017 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 <QtCore/QLoggingCategory>

#include "remotedevicemanager_p.h"
#include "bluez5_helper_p.h"
#include "device1_bluez5_p.h"
#include "objectmanager_p.h"

QT_BEGIN_NAMESPACE

Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)

/*!
 * Convenience wrapper around org.bluez.Device1 management
 *
 * Very simple and not thread safe.
 */

RemoteDeviceManager::RemoteDeviceManager(
        const QBluetoothAddress &address, QObject *parent)
    : QObject(parent), localAddress(address)
{
    if (!isBluez5())
        return;

    bool ok = false;
    adapterPath = findAdapterForAddress(address, &ok);
    if (!ok || adapterPath.isEmpty()) {
        qCWarning(QT_BT_BLUEZ) << "Cannot initialize RemoteDeviceManager";
    }
}

bool RemoteDeviceManager::scheduleJob(
        JobType job, const QVector<QBluetoothAddress> &remoteDevices)
{
    if (adapterPath.isEmpty())
        return false;

    for (const auto& remote : remoteDevices)
        jobQueue.push_back(std::make_pair(job, remote));

    QTimer::singleShot(0, this, [this](){ runQueue(); });
    return true;
}

void RemoteDeviceManager::runQueue()
{
    if (jobInProgress || adapterPath.isEmpty())
        return;

    if (jobQueue.empty())
        return;

    jobInProgress = true;
    switch (jobQueue.front().first) {
    case JobType::JobDisconnectDevice:
        disconnectDevice(jobQueue.front().second);
        break;
    default:
        break;
    }
}

void RemoteDeviceManager::prepareNextJob()
{
    Q_ASSERT(!jobQueue.empty());

    jobQueue.pop_front();
    jobInProgress = false;

    qDebug(QT_BT_BLUEZ) << "RemoteDeviceManager job queue status:" << jobQueue.empty();
    if (jobQueue.empty())
        emit finished();
    else
        runQueue();
}

void RemoteDeviceManager::disconnectDevice(const QBluetoothAddress &remote)
{
    // collect initial set of information
    OrgFreedesktopDBusObjectManagerInterface managerBluez5(
                                               QStringLiteral("org.bluez"),
                                               QStringLiteral("/"),
                                               QDBusConnection::systemBus(), this);
    QDBusPendingReply<ManagedObjectList> reply = managerBluez5.GetManagedObjects();
    reply.waitForFinished();
    if (reply.isError()) {
        QTimer::singleShot(0, this, [this](){ prepareNextJob(); });
        return;
    }

    bool jobStarted = false;
    ManagedObjectList managedObjectList = reply.value();
    for (auto it = managedObjectList.constBegin(); it != managedObjectList.constEnd(); ++it) {
        const QDBusObjectPath &path = it.key();
        const InterfaceList &ifaceList = it.value();

        for (auto jt = ifaceList.constBegin(); jt != ifaceList.constEnd(); ++jt) {
            const QString &iface = jt.key();

            if (path.path().indexOf(adapterPath) != 0)
                continue; //devices whose path doesn't start with same path we skip

            if (iface != QStringLiteral("org.bluez.Device1"))
                continue;

            const QBluetoothAddress foundAddress(ifaceList.value(iface).value(QStringLiteral("Address")).toString());
            if (foundAddress != remote)
                continue;

            // found the correct Device1 path
            OrgBluezDevice1Interface* device1 = new OrgBluezDevice1Interface(QStringLiteral("org.bluez"),
                                                                             path.path(),
                                                                             QDBusConnection::systemBus(),
                                                                             this);
            QDBusPendingReply<> asyncReply = device1->Disconnect();
            QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(asyncReply, this);
            const auto watcherFinished = [this, device1](QDBusPendingCallWatcher* call) {
                call->deleteLater();
                device1->deleteLater();
                prepareNextJob();
            };
            connect(watcher, &QDBusPendingCallWatcher::finished, this, watcherFinished);
            jobStarted = true;
            break;
        }
    }

    if (!jobStarted) {
        qDebug(QT_BT_BLUEZ) << "RemoteDeviceManager JobDisconnectDevice failed";
        QTimer::singleShot(0, this, [this](){ prepareNextJob(); });
    }
}

QT_END_NAMESPACE
