#include "UdpNotifier.h"
#include "QsLog/QsLog.h"
#include "PreDefined.h"

UdpNotifier& UdpNotifier::Instance()
{
    static UdpNotifier udpNoti;
    return udpNoti;
}

bool UdpNotifier::Start(int port)
{
    m_udpPort = port;

    bool result = true;
    if(!_CreateServer())
    {
        result = false;
    }
    return result;
}

void UdpNotifier::NotifyOther()
{
    for(int i=0; i<5; i++)
    {
        m_udpServer->writeDatagram(QByteArray(UDP_KEY), QHostAddress::Broadcast, m_udpPort);
    }
    return;
}

bool UdpNotifier::_CreateServer()
{
    bool result = true;
    m_udpServer = new QUdpSocket(this);

    if(!m_udpServer->bind(m_udpPort))
    {
        QLOG_WARN() << QString("udpnotifier bind failed![%1]").arg(m_udpServer->errorString());
        emit udpError(m_udpServer->errorString());
        result = false;
    }else
    {
        QLOG_INFO() << QString("udpnotifier start with port[%1]").arg(m_udpPort);
    }

    connect(m_udpServer, SIGNAL(readyRead()), this, SLOT(onRecvData()));
    return result;
}

void UdpNotifier::onRecvData()
{
    QHostAddress sender;
    quint16 port;
    while(m_udpServer->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(m_udpServer->pendingDatagramSize());
        m_udpServer->readDatagram(datagram.data(), datagram.size(), &sender, &port);

        // 过滤本机发出的广播消息
        foreach(QHostAddress adr, QHostInfo::fromName(QHostInfo::localHostName()).addresses())
        {
            if(adr.toIPv4Address()==sender.toIPv4Address())
            {
                return;
            }
        }
        QLOG_TRACE() << QString("udpnotifier recv data[%1] from[%2]").arg(datagram.data()).arg(sender.toString());

        if(!QString(datagram.data()).compare(UDP_KEY))
        {
            emit beSlave();
        }
    }
    return;
}
