#include "search_dev.hpp"
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <zlog.h>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>

extern zlog_category_t *zct;

static const char* MULTICAST_HOST_NAME1 = "224.0.0.1"; //组播接收平台搜索信号地址
static const int MULTICAST_PORT_RECV1 = 7301;          //组播接收端口
static const int MULTICAST_PORT_SEND = 7302;           //根据接收组播udp发送端口

SearchDev::SearchDev(boost::asio::io_service& ioservice) : mSockRecv_1(ioservice), mListenEP1(boost::asio::ip::udp::v4(), MULTICAST_PORT_RECV1), mSendEndpoint1(boost::asio::ip::address::from_string(MULTICAST_HOST_NAME1), MULTICAST_PORT_SEND) { Init(); }

SearchDev::~SearchDev() { Stop(); }

void SearchDev::Init() {
    try {
        mSockRecv_1.open(mListenEP1.protocol());
        mSockRecv_1.set_option(boost::asio::ip::udp::socket::reuse_address(true));
        mSockRecv_1.bind(mListenEP1);
        mSockRecv_1.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::address_v4::from_string(MULTICAST_HOST_NAME1)));
        mSockRecv_1.set_option(boost::asio::ip::multicast::enable_loopback(false));
    } catch (boost::system::system_error& e) {
        std::cout << e.what() << std::endl;
    }
}

void SearchDev::GwRouteInit() {}

void SearchDev::HandleSend_1(const char* pMsg, const boost::system::error_code& pEc) {
    if (pEc) {
        zlog_info(zct, "send udp error 7302");
    } else {
        zlog_info(zct, "send udp ok 7302");
    }
}

void SearchDev::MultiCastRecv() { MultiCastRecv_1(); }

void SearchDev::MultiCastRecv_1() {
    memset(mRecvBuf1, 0, BUF_LENGTH);

    mSockRecv_1.async_receive_from(boost::asio::buffer(mRecvBuf1, BUF_LENGTH), mRecvEP1, boost::bind(&SearchDev::HandleRecv_1, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

void SearchDev::HandleRecv_1(const boost::system::error_code& pEc, size_t pBytesRecv) {
    if (!pEc) {
        zlog_info(zct, "mRecvBuf1 : %s", mRecvBuf1);
        std::string data = std::string(mRecvBuf1);
        Json::Value jsData;
        Json::Reader recvReader;
        Json::Value JsonVal;
        Json::FastWriter fw;
        if (recvReader.parse(data, jsData)) {
            int cmdType = atoi(jsData["cmd"].asString().c_str());
            switch (cmdType) {
                case 4: {
                    std::string status = jsData["status"].asString();
                    if (status.compare("REQ") == 0) {
                        jsData["dataWatchNo"] = GlobalConfig::MacAddr_G.c_str();
                        jsData["localServerIpAddress"] = GlobalConfig::IpAddr_G;
                        jsData["status"] = "ACK";
                        jsData["DeviceType"] = "WirelessGateWay";
                        std::string strData = fw.write(jsData);
                        zlog_info(zct, "send info %s  ip: %s\n", strData.c_str(), mRecvEP1.address().to_string().c_str());
                        boost::asio::ip::udp::endpoint remoteEP(boost::asio::ip::address::from_string(mRecvEP1.address().to_string()), MULTICAST_PORT_SEND);
                        mSockRecv_1.async_send_to(boost::asio::buffer(strData), remoteEP, boost::bind(&SearchDev::HandleSend_1, this, "SockRecv_1_1", boost::asio::placeholders::error));
                    }
                } break;
                default: break;
            }
        } else {
            zlog_error(zct, "parse error\n");
        }
        MultiCastRecv_1();
    } else {
    }
}

void SearchDev::Run() {
    // mIoSev.run();
}

void SearchDev::Stop() {
    // if (!mIoSev.stopped())
    //   mIoSev.stop();
}

void SearchDev::Restart() { Init(); }
