#include "tmpdevclear.h"
#include "daemon.h"
#include "sessiondbusregister.h"

#include <functional>
#include <algorithm>
#include <QDateTime>
#include <QTimer>
#include <QDebug>
#include <QMutexLocker>
#include <KF5/BluezQt/bluezqt/device.h>

extern QString global_active_connection_dev;
extern SessionDbusRegister * global_sess;

//间隔清理不可见设备时间
const qint64 interval = 30*1000;

TmpDevClear* TmpDevClear::_instant = nullptr;

TmpDevClear *TmpDevClear::getInstant()
{
    if (nullptr == _instant) {
        _instant = new TmpDevClear();
    }

    return _instant;
}

void TmpDevClear::init()
{
    if (!baseTime) {
        baseTime =  new QTimer(this);
        baseTime->setInterval(interval / 6);
        connect(baseTime,&QTimer::timeout,this,&TmpDevClear::removeConnectionFromMap);
    }
    qDebug() << "TmpDevClear currentThreadId :" << QThread::currentThreadId();


    for (auto dev : Daemon::_DefualtAdapter.data()->devices()) {
        qDebug() << Q_FUNC_INFO <<dev.data()->address() << dev.data()->name();
        if (connections.end() != connections.find(dev.data()->address())) {
            QObject::disconnect(connections[dev.data()->address()]);
        }

        devUpdates[dev.data()->address()] = QDateTime::currentMSecsSinceEpoch();
        connections[dev.data()->address()] = connect(dev.data(),&BluezQt::Device::deviceChanged,this,&TmpDevClear::rssiChanaged);
    }
    Daemon::_DefualtAdapter->disconnect(this);
    connect(Daemon::_DefualtAdapter.data(),&BluezQt::Adapter::deviceAdded,this,[=](BluezQt::DevicePtr devAdd){
        if (connections.end() != connections.find(devAdd.data()->address())) {
            QObject::disconnect(connections[devAdd.data()->address()]);
        }

        devUpdates[devAdd.data()->address()] = QDateTime::currentMSecsSinceEpoch();
        connections[devAdd.data()->address()] = connect(devAdd.data(),&BluezQt::Device::deviceChanged,this,&TmpDevClear::rssiChanaged);
    });

    baseTime->start();
}

void TmpDevClear::fini(void)
{
    Daemon::_DefualtAdapter->disconnect(this);
    devUpdates.clear();

    //蓝牙设备删除，关联的信号也会删除
    connections.clear();
}

TmpDevClear::TmpDevClear(QObject *parent): QObject(parent)
{

}

void TmpDevClear::removeConnectionFromMap()
{
    if (Daemon::_DefualtAdapter.isNull() || !Daemon::_DefualtAdapter->isPowered())
        return;
    qDebug() << Q_FUNC_INFO << "start" << devUpdates.size() << connections.size();


    for(QString iter : m_cleardev)
    {
        BluezQt::DevicePtr devptr = Daemon::_DefualtAdapter.data()->deviceForAddress(iter);
        //能够搜索到设备，且处于未配对未连接状态，从底层移除设备
        if(!devptr.isNull() && !devptr.data()->isPaired() && !devptr.data()->isConnected()
                && devptr->address() != global_active_connection_dev)
        {
            qDebug() << "clear dev: " << iter;
            Daemon::_DefualtAdapter.data()->removeDevice(devptr);
        }
        //能够搜索到设备，且设备处于配对或者连接状态，加入列表
        else if(!devptr.isNull() && (devptr->isPaired() || devptr->isConnected()))
        {
            qDebug() << "add dev: " << iter;
            devUpdates[devptr->address()] = QDateTime::currentMSecsSinceEpoch();
            connections[devptr->address()] = connect(devptr.data(),&BluezQt::Device::deviceChanged,this,&TmpDevClear::rssiChanaged);
        }
        //搜索不到设备，说明已经被移除了
    }

    m_cleardev.clear();
    for (QMap<QString,qint64>::iterator iter = devUpdates.begin(); iter != devUpdates.end();) {
        if ((iter.value()+interval) <= QDateTime::currentMSecsSinceEpoch()) {

            BluezQt::DevicePtr devptr = Daemon::_DefualtAdapter.data()->deviceForAddress(iter.key());
            //发起配对时，设备非pair状态但是是连接状态
            if (!devptr.isNull() && !devptr.data()->isPaired() && !devptr.data()->isConnected()
                    && devptr->address() != global_active_connection_dev) {
                disconnect(connections[iter.key()]);
                connections.remove(iter.key());
                iter = devUpdates.erase(iter);
                m_cleardev.append(devptr->address());
            }
            //设备已被移除
            else if(devptr.isNull())
            {
                disconnect(connections[iter.key()]);
                connections.remove(iter.key());
                iter = devUpdates.erase(iter);
            }
            else {
                iter++;
            }
        } else {
            iter++;
        }
    }
    if(m_cleardev.size() > 0)
    {
        qDebug() << "clear dev: " << m_cleardev;
        global_sess->clearBluetoothDev(m_cleardev);
    }
}

void TmpDevClear::rssiChanaged(BluezQt::DevicePtr dev)
{
    Q_UNUSED(dev);

    devUpdates[dev.data()->address()] = QDateTime::currentMSecsSinceEpoch();
}

void TmpDevClear::updateTime(const QString & addr)
{
    if(devUpdates.contains(addr))
    {
        devUpdates[addr] = QDateTime::currentMSecsSinceEpoch();
    }
}

TmpDevClear::~TmpDevClear()
{

}


