#include "daemon.h"
#include <QDateTime>
#include <QFile>
#include "sessiondbusregister.h"


namespace BluezQt
{
    extern void bluezqt_initFakeBluezTestRun();
}


extern "C" {
    #include <string>
    #include <stdlib.h>
}

extern bool global_activeconn_switch;
extern SessionDbusRegister * global_sess;
extern bool global_DefaultAdapterPower;
extern bool global_need_reconnect;

const QString SERVICE   = "com.ukui.bluetooth";
const QString PATH      = "/com/ukui/bluetooth";
const QString INTERFACE = "com.ukui.bluetooth";

bool global_systemSleepFlag = false; //系统睡眠标志
bool global_needInit = true;

Daemon * global_daemon = nullptr;

//初始化蓝牙功能的时间
qint64 global_InitBluetoothTime = 0;

const static QString UKUIBT_UPGRADE_TMPFILE  =  QDir::homePath() + "/.cache/ukuibt_upgrade.tmp";

/************************************************
 * @brief  判断是否存在给定的程序启动参数
 * @param  option 启动参数
 * @return 存在返回true，否则返回false
*************************************************/
static inline bool findStartupOptions(const QString option)
{
    if (QCoreApplication::arguments().size() == 1)
        return false;

    return !(QCoreApplication::arguments().indexOf(option) == -1);
}

static inline void PendingCallProcessingFunc(BluezQt::PendingCall *call)
{
    QObject::connect(call,&BluezQt::PendingCall::finished,[=](BluezQt::PendingCall *newCall){
        if (newCall->error() != 0)
            qWarning() << newCall->errorText();
    });
}

/************************************************
 * @brief  判断传入的str是否是有效的mac地址
 * @param  str 需要判断的字符串
 * @return 有效mac地址返回true，否则返回false
*************************************************/
static bool isAddress(const QString str)
{

    return true;
}

BluezQt::AdapterPtr Daemon::_DefualtAdapter = nullptr;
BluezQt::Manager*   Daemon::_BluezManager   = nullptr;

Daemon::Daemon(QObject *parent) :
    QObject(parent),
    _mConfig(new Config(this))
{
    global_daemon = this;
    //BluezQt::bluezqt_initFakeBluezTestRun();

    qDebug() << Q_FUNC_INFO << QCoreApplication::arguments() << findStartupOptions("-d");
    qDebug() << "main currentThreadId:" << QThread::currentThreadId();

    initGSettingInfo();

#ifdef EXISTS_KYSDK_DIAGNOSTICS
    _buriedPointData = new BuriedPointData();
    _buriedPointDataThread = new QThread(this);
    _buriedPointData->moveToThread(_buriedPointDataThread);
    connect(this,&Daemon::writeInData,_buriedPointData,&BuriedPointData::writeInDataSlot);
    _buriedPointDataThread->start();
#endif

    // ===== 创建rfkill的监听，并将监听逻辑放入子线程 ====== START =============
    _rfkill = new Rfkill();
    _rfkillThread = new QThread(this);
    _rfkill->moveToThread(_rfkillThread);
    connect(_rfkill,&Rfkill::rfkillStatusChanged,this,&Daemon::rfkillStatusChange);
    connect(this,&Daemon::startThread,_rfkill,&Rfkill::init);
    _rfkillThread->start();
    emit startThread();
    // ============================= END ==================================
}

Daemon::~Daemon()
{
    qInfo() << Q_FUNC_INFO << "Daemon program exit!!!!";
    if (_rfkillThread) {
        _rfkillThread->quit();
        _rfkillThread->wait();
        _rfkillThread->deleteLater();
    }
    if (_rfkill)
        _rfkill->deleteLater();
}

void Daemon::sendFile(QString addr,QString filename)
{
    qInfo() << Q_FUNC_INFO << QString("%1 : Send file : %2").arg(addr).arg(filename);
    if (filename.isNull()||
        filename.isEmpty()||
        addr.isEmpty()||
        addr.isNull())
        return;

    if (!_ObexManager)
        initObexManager();

    if (!_ObexManager->isOperational())
        registerObexAgent();

    if (isAddress(addr)) {
        selected_file = filename;
        qInfo() << Q_FUNC_INFO << QString("Send file : %1").arg(selected_file);
        if(!selected_file.isNull()){
            fileTransferSessionCreator(addr, selected_file);
        }
    } else {

    }
}

//void Daemon::propertyChanged(QString name, QVariantMap map, QStringList list)
//{
//    for (QVariantMap::const_iterator it = map.cbegin(), end = map.cend(); it != end; ++it) {
//        qDebug() << "property: " << it.key() << " value: " << it.value();
//        if(it.key() == "Transferred"){
//            QVariant value = it.value();
//            transfer_widget->set_m_progressbar_value(value.value<quint64>());
//        }else if(it.key() == "Status"){
//            QVariant value = it.value();
//            if(value.value<QString>() == "active"){
//                transfer_widget->init_m_progressbar_value(transfer_file_size);
//            }else if(value.value<QString>() == "error"){
//                qDebug() << Q_FUNC_INFO << __LINE__;
//                filePtr->cancel();
//            }
//            transfer_widget->get_transfer_status(value.value<QString>());
//        }
//    }
//    for (const auto& element : list) {
//        qDebug() << "list element: " << element;
//    }
//}

void Daemon::closeSession()
{
    if(pre_session.path() != ""){
        if (nullptr != filePtr)
        {
            qDebug() << Q_FUNC_INFO << pre_session.path() << filePtr->objectPath().path();
            //防止因连接失败而导致间隙时间置为Queued状态无法回归正常状态
            QDBusMessage statusChanged  = QDBusMessage::createSignal("/com/ukui/bluetooth",
                                                                            "com.ukui.bluetooth",
                                                                            "statusChanged");
            QMetaEnum metaEnum = QMetaEnum::fromType<BluezQt::ObexTransfer::Status>();
            statusChanged << metaEnum.valueToKey(BluezQt::ObexTransfer::Error) << transferDev << filePtr->objectPath().path();
            QDBusConnection::sessionBus().send(statusChanged);

            BluezQt::PendingCall * stopFileSend = filePtr->cancel();
            connect(stopFileSend,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){
                qDebug() << Q_FUNC_INFO  << q->errorText() << __LINE__;
                _ObexManager->removeSession(pre_session);
            });
        } else {
            _ObexManager->removeSession(pre_session);
        }
    }
}

void Daemon::setBluetoothBlock(bool)
{

}

/************************************************
 * @brief  监听gsetting key的改变，并同步更新对应的value
 * @param  key value改变的键名
 * @return null
*************************************************/
void Daemon::gsettingsChangedSlot(const QString &key)
{
    if (_mGsetting.keys().contains(key)) {
        qInfo() << Q_FUNC_INFO << QString("%1 changed, old value %2, new value %3").arg(key).arg(_mGsetting[key].toString()).arg(Config::gsetting->get(key).toString());
        _mGsetting[key] = Config::gsetting->get(key);

    }
    if(GSETTING_STR_ACTIVE_CONNECTION_TRAN == key || GSETTING_STR_ACTIVE_CONNECTION == key)
    {
        _mGsetting[GSETTING_STR_ACTIVE_CONNECTION] = Config::gsetting->get(key);
        global_activeconn_switch = Config::gsetting->get(key).toBool();
        qInfo() << Q_FUNC_INFO << GSETTING_STR_ACTIVE_CONNECTION << global_activeconn_switch;
    }
}

void Daemon::rfkillStatusChange(int status)
{
    qInfo() << Q_FUNC_INFO << "rfkill status changed" << status << QThread::currentThreadId();
    int ret = 0;
    switch (status) {
    case 0:
        ret = initBluezManager();
        if (ret == -1)
            return;

        qInfo() << Q_FUNC_INFO << "init defualt Adapter!!!" << _BluezManager->isBluetoothOperational();

        if (findStartupOptions("-o") || findStartupOptions("--obex"))
        {
            //非华为机器才存在文件传输功能
            if(Environment::HUAWEI != envPC)
            {
                initObexManager();
            }
        }

        monitorDbusSignal();
        break;
    case 1:
        break;
    //无蓝牙节点
    case 4:
    {
        //蓝牙插件不显示
        Config::ukccGsetting->set("show",QVariant(false));
        qInfo() << Q_FUNC_INFO << "no bluetooth rfkill, show set false";
    }
        break;
    default:
        break;
    }
}

/************************************************
 * @brief  将gsettings配置存入map统一管理
 * @param  null
 * @return null
*************************************************/
void Daemon::initGSettingInfo()
{
    _mGsetting.clear();
    _mGsetting[GSETTING_STR_BLUETOOTH_POWER_SWTICH]         = Config::gsetting->get(GSETTING_STR_BLUETOOTH_POWER_SWTICH);
    _mGsetting[GSETTING_STR_BLUETOOTH_DISCOVERABLE_SWTICH]  = Config::gsetting->get(GSETTING_STR_BLUETOOTH_DISCOVERABLE_SWTICH);
    _mGsetting[GSETTING_STR_FINALLY_CONNECT_THE_DEVICE]     = Config::gsetting->get(GSETTING_STR_FINALLY_CONNECT_THE_DEVICE);
    _mGsetting[GSETTING_STR_ADAPTER_ADDRESS]                = Config::gsetting->get(GSETTING_STR_ADAPTER_ADDRESS);
    _mGsetting[GSETTING_STR_FILE_SAVE_PATH]                 = Config::gsetting->get(GSETTING_STR_FILE_SAVE_PATH);
    _mGsetting[GSETTING_STR_ADAPTER_ADDRESS_LIST]           = Config::gsetting->get(GSETTING_STR_ADAPTER_ADDRESS_LIST);
    _mGsetting[GSETTING_STR_ACTIVE_CONNECTION]              = Config::gsetting->get(GSETTING_STR_ACTIVE_CONNECTION);
    global_activeconn_switch = _mGsetting[GSETTING_STR_ACTIVE_CONNECTION].toBool();
    global_DefaultAdapterPower = _mGsetting[GSETTING_STR_BLUETOOTH_POWER_SWTICH].toBool();
    connect(Config::gsetting,SIGNAL(changed(QString)),this,SLOT(gsettingsChangedSlot(QString)));

    if(QFile::exists(UKUIBT_UPGRADE_TMPFILE))
    {
        global_DefaultAdapterPower = true;
        Config::gsetting->set(GSETTING_STR_BLUETOOTH_POWER_SWTICH,QVariant(global_DefaultAdapterPower));
        QFile::remove(UKUIBT_UPGRADE_TMPFILE);
    }
}

/************************************************
 * @brief  初始系统蓝牙服务，设置设备授权代理
 * @param  null
 * @return null
*************************************************/
int Daemon::initBluezManager()
{
    qInfo() << Q_FUNC_INFO << " start";
    if (_BluezManager)
        return -1;

    //启动_BluezManager, 直到成功启动退出循环
    while(true)
    {
        _BluezManager = new BluezQt::Manager(this);
        BluezQt::InitManagerJob *job = _BluezManager->init();
        job->exec();

        if(!_BluezManager->isOperational() || !_BluezManager->isInitialized()){
            qWarning("BlueZ system daemon is not running");
            delete _BluezManager;
            _BluezManager = nullptr;
            qWarning("BlueZ system daemon restart");
            QThread::sleep(5);
        }
        else
        {
            qInfo("BlueZ system daemon start suc");
            break;
        }
    }

    if(nullptr == _BluezManager)
    {
        qWarning("null _BluezManager");
        return -1;
    }

    //_BluezManager->disconnect(this);
    connect(_BluezManager,&BluezQt::Manager::operationalChanged,this,[=](bool operational){
        qInfo() << Q_FUNC_INFO << "operationalChanged: " << operational;
    });

    connect(_BluezManager,&BluezQt::Manager::adapterAdded,this,[=](BluezQt::AdapterPtr adapter){
        qInfo() << Q_FUNC_INFO << "adapterAdded" << adapter->address() << adapter->isPowered()<< __LINE__;
        emit global_sess->adapterAddSignal(adapter->address());

        //新增第一个蓝牙适配器，初始化蓝牙功能
        if(Daemon::_BluezManager->adapters().size() == 1)
        {
            global_needInit = true;
            Daemon::_DefualtAdapter = adapter;
            this->__launch_bluetooth();
        }
        else if(nullptr == _DefualtAdapter && Daemon::_BluezManager->adapters().size() > 1)
        {
            global_needInit = true;
            Daemon::_DefualtAdapter = this->getDefualtAdapter();
            this->__launch_bluetooth();
        }
        //设置控制面板默认显示窗口状态
        Config::ukccGsetting->set("show",QVariant(true));
    });

    connect(_BluezManager,&BluezQt::Manager::adapterRemoved,this,[=](BluezQt::AdapterPtr adapter){
        qInfo() << Q_FUNC_INFO << "adapterRemoved" << __LINE__;
        emit global_sess->adapterRemoveSignal(adapter.data()->address());

        //如果移除的是默认蓝牙适配器
        if(!Daemon::_DefualtAdapter.isNull() && adapter->address() == Daemon::_DefualtAdapter->address())
        {
            qInfo() << Q_FUNC_INFO << "default adapter removed, addr : " << adapter->address();
            Daemon::_DefualtAdapter = this->getDefualtAdapter();
            if(!_DefualtAdapter.isNull())
            {
               global_needInit = true;
               qInfo() << Q_FUNC_INFO << "default adapter init, addr : " << Daemon::_DefualtAdapter->address();
               emit global_sess->defaultAdapterChanged(Daemon::_DefualtAdapter->address());
               this->__launch_bluetooth();
            }
            else
            {
                qInfo() << Q_FUNC_INFO << "null default adapter";
            }
        }
    });

    connect(_BluezManager,&BluezQt::Manager::allAdaptersRemoved,this,[=](void)
    {
         qInfo() << Q_FUNC_INFO << "allAdaptersRemoved";
         global_needInit = true;

         _DefualtAdapter = nullptr;

         //未进入睡眠
         if(!global_systemSleepFlag)
            Config::ukccGsetting->set("show",QVariant(false));
    });

    connect(_BluezManager,&BluezQt::Manager::usableAdapterChanged,this,[=](BluezQt::AdapterPtr ptr){
        qInfo() << Q_FUNC_INFO;
    });

    connect(_BluezManager,&BluezQt::Manager::adapterChanged,this,[=](BluezQt::AdapterPtr ptr){
        Q_UNUSED(ptr)
        //qInfo() << Q_FUNC_INFO << "adapterChanged";
    });

    connect(_BluezManager,&BluezQt::Manager::bluetoothOperationalChanged,this,[=](bool operational){
        qInfo() << Q_FUNC_INFO << "bluetoothOperationalChanged" << operational;

    });

    connect(_BluezManager,&BluezQt::Manager::bluetoothBlockedChanged,this,[=](bool operational){
        qInfo() << Q_FUNC_INFO << "bluetoothBlockedChanged" << operational;
        if(operational)
        {
            global_needInit = true;
            emit global_sess->defaultAdapterPowerChanged(false);
        }
        else
        {
            this->__launch_bluetooth();
        }
    });

    launchTrayUI();

    if(_BluezManager->adapters().size() > 0)
    {
        for (auto item : _BluezManager->adapters())
        {
            qInfo() << "emit add adapter signal, addr : " << item->address() << " name : "<< item->name();
            emit _BluezManager->adapterAdded(item);
        }
    }
    else
    {
        //未进入睡眠
        if(!global_systemSleepFlag)
            Config::ukccGsetting->set("show",QVariant(false));
    }
    return 0;
}

//存在默认适配器后，启动蓝牙服务功能
void Daemon::__launch_bluetooth(void)
{
    qInfo() << Q_FUNC_INFO;

    if(_DefualtAdapter.isNull())
    {
        qWarning() << Q_FUNC_INFO << "null _DefualtAdapter";
        return;
    }

    if(_BluezManager->isBluetoothBlocked())
    {
        qWarning() << Q_FUNC_INFO << "block " << _BluezManager->isBluetoothBlocked();
        return;
    }

    if(!global_needInit)
    {
        qWarning() << Q_FUNC_INFO << "not need init";
        return;
    }

    global_needInit = false;

    launchDbusSignal();

    registerBluezAgent();

    BluezQt::PendingCall * pending = nullptr;
    int ret = 0;

    //记录初始化时间，若5s内设置的蓝牙状态与蓝牙实际状态不一致，重新设置蓝牙状态
    global_InitBluetoothTime = QDateTime::currentMSecsSinceEpoch();

    while(true)
    {
        qInfo() << Q_FUNC_INFO << "set power: " << global_DefaultAdapterPower
                << ", adapter power: " << _DefualtAdapter->isPowered();
        pending = _DefualtAdapter->setPowered(global_DefaultAdapterPower);
        connect(pending,&BluezQt::PendingCall::finished,this,[=, &ret](BluezQt::PendingCall *call)
        {
            ret = call->error();
            qInfo() << Q_FUNC_INFO << "power: error: " << call->error() << ", errorText: " <<call->errorText();
        });
        pending->waitForFinished();
        qInfo() << Q_FUNC_INFO <<  "adapter power: " << _DefualtAdapter->isPowered();
        if(0 == ret)
        {
            break;
        }
        else
        {
             QThread::msleep(100);
        }
    }

    global_need_reconnect = true;

    //发送适配器改变信号
    if(_DefualtAdapter->isPowered() == global_DefaultAdapterPower)
    {
        emit _DefualtAdapter->poweredChanged(_DefualtAdapter->isPowered());
    }

    qInfo() << Q_FUNC_INFO << __LINE__;
}

void Daemon::launchDefaultBluetooth(void)
{
    qInfo() << Q_FUNC_INFO;
    global_needInit = true;
    this->__launch_bluetooth();
}

void Daemon::setDefaultDiscoverble()
{
    BluezQt::PendingCall * pending = _DefualtAdapter->setDiscoverable(Config::gsetting->get(GSETTING_STR_BLUETOOTH_DISCOVERABLE_SWTICH).toBool());
    connect(pending,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *call)
    {
         qInfo() << Q_FUNC_INFO << "discoverble: error: " << call->error() << ", errorText: " <<call->errorText();
    });
    pending->waitForFinished();
}


void Daemon::continueSendFiles(QString filename) {
    qDebug() << Q_FUNC_INFO << filename << __LINE__;
    BluezQt::PendingCall *transfer = opp->sendFile(filename);
    qDebug() << Q_FUNC_INFO << transfer->error() << transfer->errorText();
    connect(transfer,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *call){
        qDebug() << Q_FUNC_INFO << __LINE__;
        QVariant v = call->value();
        filePtr = v.value<BluezQt::ObexTransferPtr>();
        QString transferPath;
        if(!filePtr.isNull()){
            transferPath = filePtr->objectPath().path();
            transfer_file_size = filePtr->size();
            qDebug() << Q_FUNC_INFO << "Sending file size:" << transfer_file_size << filePtr->type() << filePtr->name() <<__LINE__;

            QDBusMessage initTransferPath  = QDBusMessage::createSignal("/com/ukui/bluetooth",
                                                                            "com.ukui.bluetooth",
                                                                            "initTransferPath");
            initTransferPath << transferPath << true;

            QDBusConnection::sessionBus().send(initTransferPath);

            connect(filePtr.data(),&BluezQt::ObexTransfer::transferredChanged,this,[=](quint64 vl){
                qDebug() << Q_FUNC_INFO << "Sending file size:" << vl << __LINE__;
                QDBusMessage transferredChanged  = QDBusMessage::createSignal("/com/ukui/bluetooth",
                                                                                "com.ukui.bluetooth",
                                                                                "transferredChanged");
                transferredChanged << vl << transferPath;

                QDBusConnection::sessionBus().send(transferredChanged);
            });
            connect(filePtr.data(),&BluezQt::ObexTransfer::statusChanged,this,[=](BluezQt::ObexTransfer::Status status){
                qDebug() << Q_FUNC_INFO << "Sending file size:" << status << __LINE__;
                QDBusMessage statusChanged  = QDBusMessage::createSignal("/com/ukui/bluetooth",
                                                                                "com.ukui.bluetooth",
                                                                                "statusChanged");
                QMetaEnum metaEnum = QMetaEnum::fromType<BluezQt::ObexTransfer::Status>();
                statusChanged << QString(metaEnum.valueToKey(status)) << transferDev << transferPath;
                QDBusConnection::sessionBus().send(statusChanged);
            });
        }else{
            QDBusMessage statusChanged  = QDBusMessage::createSignal("/com/ukui/bluetooth",
                                                                            "com.ukui.bluetooth",
                                                                            "statusChanged");
            statusChanged << QString("Error") << transferDev << transferPath;

            QDBusConnection::sessionBus().send(statusChanged);
        }
    });
}

/************************************************
 * @brief  初始化自定义设备授权代理, 并将初始化的代理设置为默认的设备授权代理
 * @param  null
 * @return null
*************************************************/
void Daemon::registerBluezAgent()
{
    qInfo() << Q_FUNC_INFO << "register Bluez Agent";
    if (!_BluezAgent)
        _BluezAgent = new BluetoothAgent(this);

    PendingCallProcessingFunc(_BluezManager->registerAgent(_BluezAgent));
}

void Daemon::fileTransferSessionCreator(QString address,QString filename)
{
    qDebug() << Q_FUNC_INFO << __LINE__;
    QMap<QString,QVariant> map;

    map["Source"] = _DefualtAdapter->address();
    map["Target"] = "OPP";

    if (!_ObexManager->isOperational()) {
        connect(_ObexManager, &BluezQt::ObexManager::operationalChanged, this, [=](bool operational) {
            Q_UNUSED(operational)
            fileTransferSessionCreator(address, filename);
            qDebug() << Q_FUNC_INFO << __LINE__;
            disconnect(_ObexManager, &BluezQt::ObexManager::operationalChanged, nullptr, nullptr);
        });
        return;
    }

    transferDev = address;

    BluezQt::PendingCall *target = _ObexManager->createSession(address,map);
    qDebug() << Q_FUNC_INFO << target->error() << target->errorText();
    connect(target,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *call){
        QVariant v = call->value();
        QDBusObjectPath session = v.value<QDBusObjectPath>();

        pre_session = session;
        opp = new BluezQt::ObexObjectPush(session);
        if (QDBusConnection::sessionBus().connect(SERVICE, PATH,
                INTERFACE, "continueSendFilesSignal", this,
                SLOT(continueSendFiles(QString)))) {
            qDebug() << "devConnectStatusSignal signal connected successfully to slot";
        } else {
            qDebug() << "devConnectStatusSignal signal connection was not successful";
        }

        //将点击发送到设备连接之间的时间设置为queued状态，防止间隙异常操作
        QDBusMessage statusChanged  = QDBusMessage::createSignal("/com/ukui/bluetooth",
                                                                        "com.ukui.bluetooth",
                                                                        "statusChanged");
        QMetaEnum metaEnum = QMetaEnum::fromType<BluezQt::ObexTransfer::Status>();
        statusChanged << metaEnum.valueToKey(BluezQt::ObexTransfer::Queued) << transferDev << QString("");
        QDBusConnection::sessionBus().send(statusChanged);

        continueSendFiles(filename);
    });
}

/************************************************
 * @brief  初始文件传输服务，设置文件传输代理
 * @param  null
 * @return null
*************************************************/
void Daemon::initObexManager()
{
    if (_ObexManager)
        return;

    _ObexManager = new BluezQt::ObexManager(this);
    BluezQt::InitObexManagerJob *obex_job = _ObexManager->init();
    obex_job->exec();

    registerObexAgent();
}

/************************************************
 * @brief  初始化自定义文件传输代理 , 并将初始化的代理设置为默认的文件传输代理
 * @param  null
 * @return null
*************************************************/
void Daemon::registerObexAgent()
{
    qDebug() << Q_FUNC_INFO << __LINE__;
    if (!_ObexAgent)
        _ObexAgent = new BluetoothObexAgent(this);

    qInfo() << Q_FUNC_INFO << __LINE__;
    if(!_ObexManager->isOperational()){
        BluezQt::PendingCall *call = _ObexManager->startService();
        connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *q){
            QTimer::singleShot(1000,this,[=]{
                PendingCallProcessingFunc(_ObexManager->registerAgent(_ObexAgent));
            });
        });
    }else{
        PendingCallProcessingFunc(_ObexManager->registerAgent(_ObexAgent));
    }
}

void Daemon::launchTrayUI()
{
    Config::LaunchUI();
}

/************************************************
 * @brief  从系统的gsetting和自定义逻辑中返回默认的配置器
 * @param  null
 * @return 默认适配器共享指针 BluezQt::AdapterPtr
*************************************************/
BluezQt::AdapterPtr Daemon::getDefualtAdapter()
{
    qDebug() << Q_FUNC_INFO << __LINE__;

    BluezQt::AdapterPtr ptr = nullptr;

    if(_BluezManager->adapters().size() == 0)
    {
        ;
    }
    else if(_BluezManager->adapters().size() == 1)
    {
        Config::gsetting->set(GSETTING_STR_ADAPTER_ADDRESS,QVariant::fromValue(_BluezManager->adapters().at(0)));
        ptr = _BluezManager->adapters().at(0);
    }
    else
    {
         if(_mGsetting[GSETTING_STR_ADAPTER_ADDRESS].toString().isEmpty())
         {
             Config::gsetting->set(GSETTING_STR_ADAPTER_ADDRESS,QVariant::fromValue(_BluezManager->adapters().at(0).data()->address()));
             ptr =  _BluezManager->adapters().at(0);
         }
         else
         {
             ptr = _BluezManager->adapterForAddress(_mGsetting[GSETTING_STR_ADAPTER_ADDRESS].toString());
             if(ptr.isNull())
             {
                 Config::gsetting->set(GSETTING_STR_ADAPTER_ADDRESS,QVariant::fromValue(_BluezManager->adapters().at(0).data()->address()));
                 ptr =  _BluezManager->adapters().at(0);
             }
         }
    }

    if(ptr.isNull())
    {
        qWarning("No bluetooth adapter, adaptersize = %d", _BluezManager->adapters().size());
        //未进入睡眠
        if(!global_systemSleepFlag)
            Config::ukccGsetting->set("show",QVariant(false));
    }
    else
    {
        qInfo() << "get bluetooth adapter addr : " << ptr->address() << ", name : " <<ptr->name() << " all size : "
                << _BluezManager->adapters().size();
        Config::ukccGsetting->set("show",QVariant(true));
    }

    return ptr;

}

/************************************************
 * @brief  默认适配器属性变化信号与自定义dbus信号关联
 * @param  null
 * @return null
*************************************************/
//void Daemon::connectDefualtSignal()
//{
//    qInfo() << Q_FUNC_INFO << __LINE__;
//    devScanSignal      =      createCustomSignalMsg("deviceScanResult");
//    adapterPowerSignal =      createCustomSignalMsg("defaultAdapterPowerChanged");
//    adapterScanStatusSignal = createCustomSignalMsg("defaultScanStatusChanged");
//    adapterDiscoverableSignal = createCustomSignalMsg("defaultDiscoverableChanged");

//    qDebug() << Q_FUNC_INFO << this->receivers(SIGNAL(poweredChanged(bool)));

//    connect(_DefualtAdapter.data(),&BluezQt::Adapter::deviceAdded,this,[=](BluezQt::DevicePtr devPtr){
//        devScanSignal << devPtr.data()->address() << devPtr.data()->name();
//        QDBusConnection::sessionBus().send(devScanSignal);
//    },Qt::UniqueConnection);

//    connect(_DefualtAdapter.data(),&BluezQt::Adapter::poweredChanged,this,[=](bool powered){
//        qDebug() << Q_FUNC_INFO << __LINE__;
//        adapterPowerSignal << powered;
//        qDebug() << Q_FUNC_INFO << QDBusConnection::sessionBus().send(adapterPowerSignal) << __LINE__;
//    },Qt::UniqueConnection);

//    connect(_DefualtAdapter.data(),&BluezQt::Adapter::discoveringChanged,this,[=](bool powered){
//        adapterScanStatusSignal << powered;
//        QDBusConnection::sessionBus().send(adapterScanStatusSignal);
//    },Qt::UniqueConnection);

//    connect(_DefualtAdapter.data(),&BluezQt::Adapter::discoverableChanged,this,[=](bool discoverable){
//        adapterDiscoverableSignal << discoverable;
//        QDBusConnection::sessionBus().send(adapterDiscoverableSignal);
//    },Qt::UniqueConnection);
//    qInfo() << Q_FUNC_INFO << __LINE__;
//}


/************************************************
 * @brief  创建QDBusMessage工厂函数
 * @param  signalName 需要创建的 QDBusMessage 名字
 * @return 返回类型为 QDBusMessage
*************************************************/
QDBusMessage Daemon::createCustomSignalMsg(QString signalName)
{
    return QDBusMessage::createSignal("/com/ukui/bluetooth",
                                      "com.ukui.bluetooth",
                                      signalName);
}

/************************************************
 * @brief  创建QDBusMessage工厂函数
 * @param  signalName 需要创建的 QDBusMessage 名字
 * @return 返回类型为 QDBusMessage
*************************************************/
void Daemon::monitorSleepSlot(bool sleep)
{
    qInfo () << __FUNCTION__ << "app is sleep: " << sleep << __LINE__;

    if(sleep)
    {
        global_systemSleepFlag = sleep;
        global_needInit = true;
        qInfo() << Q_FUNC_INFO << "System goes to sleep !!!";
    }
    else
    {
        qInfo() << Q_FUNC_INFO << "System wakes up from sleep !!!";

        _DefualtAdapter = getDefualtAdapter();
        if(nullptr != _DefualtAdapter)
        {
            this->__launch_bluetooth();
        }
        else
        {
            qInfo() << Q_FUNC_INFO << "null _DefualtAdapter";
        }

        //延时改变睡眠/休眠唤醒，确保大部分机型先移除设备，然后唤醒，防止出现蓝牙退出控制面板界面
        QTimer::singleShot(1000,this,[=]{
            global_systemSleepFlag = false;
            qInfo() << Q_FUNC_INFO << "global_systemSleepFlag set false";
        });

        QTimer::singleShot(5 * 1000,this,[=]{
            if(_DefualtAdapter.isNull())
            {
                qInfo() << Q_FUNC_INFO << "null _DefualtAdapter, show set false";
                Config::ukccGsetting->set("show",QVariant(false));
            }
        });
    }
    qInfo() << Q_FUNC_INFO << "end";

}

/************************************************
 * @brief 监听dbus信号
 * @param  null
 * @return null
*************************************************/
void Daemon::monitorDbusSignal()
{
    qDebug() << Q_FUNC_INFO << __LINE__;
    //部分机器在系统s3/s4会对蓝牙适配器进行移除添加操作
    if (QDBusConnection::systemBus().connect("org.freedesktop.login1", "/org/freedesktop/login1",
            "org.freedesktop.login1.Manager", "PrepareForSleep", this,
            SLOT(monitorSleepSlot(bool)))) {
        qDebug() << "PrepareForSleep signal connected successfully to slot";
    } else {
        qDebug() << "PrepareForSleep signal connection was not successful";
    }

    if (QDBusConnection::sessionBus().connect(SERVICE, PATH,
            INTERFACE, "sendFile", this,
            SLOT(sendFile(QString,QString)))) {
        qDebug() << "sendFile signal connected successfully to slot";
    } else {
        qDebug() << "sendFile signal connection was not successful";
    }

    if (QDBusConnection::sessionBus().connect(SERVICE, PATH,
            INTERFACE, "closeSessionSignal", this,
            SLOT(closeSession()))) {
        qDebug() << "closeSessionSignal signal connected successfully to slot";
    } else {
        qDebug() << "closeSessionSignal signal connection was not successful";
    }
}

void Daemon::launchDbusSignal()
{
    //qDebug() << Q_FUNC_INFO << __LINE__;
    //QDBusInterface interface(SERVICE,PATH,INTERFACE,QDBusConnection::sessionBus());
    //interface.call("connectSignal");
    //qDebug() << Q_FUNC_INFO << "end";
    global_sess->connectSignal();
}

void Daemon::devConnectSignalDbus(QString address)
{
    //停止扫描，连接完成或连接超时后继续开启扫描
    //setDefaultAdapterScanOn(false);
    //qDebug() << Q_FUNC_INFO << __LINE__;
    //QDBusMessage m = QDBusMessage::createMethodCall("com.ukui.bluetooth",
    //                                                "/com/ukui/bluetooth",
    //                                                "com.ukui.bluetooth",
    //                                                "devConnect");
    //m << address;
    //qDebug() << Q_FUNC_INFO << m.arguments().at(0).value<QString>() <<__LINE__;
    // 发送Message
    //QDBusConnection::sessionBus().call(m, QDBus::NoBlock);
    global_sess->devConnect(address);
}

void Daemon::reconnectFunc()
{
    qInfo() << Q_FUNC_INFO << "START";

    if (_DefualtAdapter.isNull()) {
        qWarning() << Q_FUNC_INFO << "Adapter is null";
        return;
    }

    if(!_DefualtAdapter.data()->isPowered())
    {
        qWarning() << Q_FUNC_INFO << "Adapter is power off";
        return;
    }

    QStringList target_list = Config::getDeviceConnectTimeList(QString("/etc/pairDevice.list"));
    qInfo() << "reconnect dev list" << target_list;
    qDebug() << Q_FUNC_INFO << target_list;
    foreach (QString dev_address, target_list) {
        if (nullptr == _DefualtAdapter)
        {
            qInfo() << Q_FUNC_INFO << "_DefualtAdapter is null!!";
            return ;
        }
        BluezQt::DevicePtr dev = _DefualtAdapter->deviceForAddress(dev_address);

        if (dev != nullptr) {
            if (dev.data()->isConnected())
                break;

            if (dev.data()->type() == BluezQt::Device::Headset ||
                dev.data()->type() == BluezQt::Device::Headphones ||
                dev.data()->type() == BluezQt::Device::AudioVideo) {

                devConnectSignalDbus(dev.data()->address());
                //dev->connectToDevice();
                //仅连接最近的蓝牙音频设备
                break;
            }
        }
    }

    qInfo() << Q_FUNC_INFO << "END";
}
void Daemon::sendWriteInData(QString settingsName ,QString action)
{
    emit global_daemon->writeInData(settingsName,action);
}

/*void Daemon::sendDevSignal(DevOperate vlaue,const QString addr)
{
    QDBusMessage sendSignal;

    switch (vlaue) {
    case DevOperate::PAIR:
        sendSignal = createCustomSignalMsg("devPairSignal");
        break;
    case DevOperate::CONNECT:
        sendSignal = createCustomSignalMsg("devConnectSignal");
        break;
    case DevOperate::DISCONNECT:
        sendSignal = createCustomSignalMsg("devDisconnectSignal");
        break;
    case DevOperate::REMOVE:
        sendSignal = createCustomSignalMsg("devRemoveSignal");
        break;
    case DevOperate::TRUST:

        break;
    default:
        sendSignal = createCustomSignalMsg("devOperateErrorSignal");
        break;
    }

    sendSignal << addr;

    QDBusConnection::sessionBus().send(sendSignal);
}*/
