#include "audiointerface.h"

#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusObjectPath>
#include <QDBusArgument>
#include <QDBusMessage>
#include <QDBusReply>

using namespace uos_ai;
AudioInterface::AudioInterface()
{
    m_meetingApps << "会议" << "Wemeet VoiceEngine";  //检测企业微信的会议场景和腾讯会议的场景
    QDBusConnection::sessionBus().connect("org.deepin.dde.Audio1", "/org/deepin/dde/Audio1",
                                          "org.freedesktop.DBus.Properties", "PropertiesChanged",
                                          this, SLOT(propertiesChanged(QString, QVariantMap, QStringList)));
    timer.setInterval(5000);
    connect(&timer, &QTimer::timeout, this, &AudioInterface::getAllSinkName);
}

void AudioInterface::propertiesChanged(QString interface, QVariantMap changedProperties, QStringList)
{
    if (interface != "org.deepin.dde.Audio1"){
        return;
    }

    for (auto iter = changedProperties.begin(); iter != changedProperties.end(); iter++) {
        if (iter.key() == "SinkInputs") {
            auto objs = qdbus_cast< QList<QDBusObjectPath> >(iter.value());
            QStringList path;
            for (auto obj : objs){
                path << obj.path();
            }
            detectedMeetingSceneFirst(path);
        }
    }
}

void AudioInterface::getAllSinkName()
{
    // 连接到DBus系统总线，这里使用session bus
    QDBusConnection connection = QDBusConnection::sessionBus();

    // 创建一个DBus接口
   // 请确保com.deepin.daemon.Audio和org.freedesktop.DBus.Properties是你的服务名和接口名
    QDBusInterface interface("org.deepin.dde.Audio1",
                             "/org/deepin/dde/Audio1",
                             "org.freedesktop.DBus.Properties",
                             connection);
    QDBusMessage message = QDBusMessage::createMethodCall(
                "org.deepin.dde.Audio1",    // 服务名
                "/org/deepin/dde/Audio1",   // 对象路径
                "org.freedesktop.DBus.Properties", // 接口名
                "Get"                      // 方法名
                );
    QVariantList params;
    params << QVariant::fromValue(QString("org.deepin.dde.Audio1"));
    params << QVariant::fromValue(QString("SinkInputs"));
    message.setArguments(params);

    QDBusReply<QVariant> reply = QDBusConnection::sessionBus().call(message);
    auto objs = qdbus_cast< QList<QDBusObjectPath> >(reply.value());
    QStringList paths;
    for (auto obj : objs){
        paths << obj.path();
    }

    detectedMeetingScene(paths);  //循环检测会议场景
}

QString AudioInterface::getSinkName(const QString &path)
{
    auto msg = QDBusMessage::createMethodCall("org.deepin.dde.Audio1", path, "org.freedesktop.DBus.Properties"
                                              , "Get");
    QVariantList params;
    params << QVariant::fromValue(QString("org.deepin.dde.Audio1.SinkInput"));
    params << QVariant::fromValue(QString("Name"));
    msg.setArguments(params);

    QDBusReply<QVariant> reply = QDBusConnection::sessionBus().call(msg);

    return reply.value().toString();
}

bool AudioInterface::detectedAiMeetingIsInstalled()
{
    QString filePath = "/opt/apps/com.aimeetingassistant.uos/files/run.sh";
    QFile file(filePath);
    if(file.exists()){
        return true;
    }
    return false;
}

void AudioInterface::detectedMeetingScene(const QStringList &paths)
{
    //判断会议助手是否安装
    if(!detectedAiMeetingIsInstalled()){
        return;
    }

    bool isDetectedMeetingScene = false;
    for ( auto path : paths){  //需要遍历完才能知道是否存在会议场景
        QString sinkName = getSinkName(path);
        if(m_meetingApps.contains(sinkName)){  //发现会议场景
            isDetectedMeetingScene = true;
            break;
        }
    }
    if(isDetectedMeetingScene){  //上面找到会议场景
        if(!m_isDetectedMeetingScene){
            m_isDetectedMeetingScene = true;
            // QMetaObject::invokeMethod(&timer, "start", Qt::QueuedConnection);
            //当前不在会议场景，提交信号到主线程，通知前端显示
            emit sigMeetingSceneChanged(true);
        }
    }else {
        if(m_isDetectedMeetingScene){
            m_isDetectedMeetingScene = false;
            //当前在会议场景，提交信号到主线程，通知前端判断是否隐藏
            emit sigMeetingSceneChanged(false);
        }
        if (timer.isActive()){
            QMetaObject::invokeMethod(&timer, "stop", Qt::QueuedConnection);
        }
    }
}

void AudioInterface::detectedMeetingSceneFirst(const QStringList &paths)
{
    bool isDetectedMeetingScene = false;
    for ( auto path : paths){  //需要遍历完才能知道是否存在会议场景
        QString sinkName = getSinkName(path);
        if(m_meetingApps.contains(sinkName)){  //发现会议场景
            isDetectedMeetingScene = true;
            break;
        }
    }
    if(isDetectedMeetingScene){  //上面找到会议场景
        if(!m_isDetectedMeetingScene){
            if (!timer.isActive())
            {
                QMetaObject::invokeMethod(&timer, "start", Qt::QueuedConnection);
            }
        }
    }
}
