#include "sinfoControl.h"
#include "QsLog.h"
#include <QJsonObject>
#include <QJsonDocument>
#include "Util/wbillcontrol.h"
#include "Util/IniDataManger.h"
#include "IniDataManger.h"

SInfoControl &SInfoControl::GetInstance()
{
    static SInfoControl sc;
    return sc;
}

void SInfoControl::Start(int port)
{
    if(this->isRunning())
    {
        return;
    }
    QLOG_TRACE() << "ListenController start";
    m_port = port;
    this->start();
}

SInfoControl::~SInfoControl()
{
    QLOG_TRACE() << "ListenController stop";
    m_bQuit = true;
    this->wait();
}

void SInfoControl::_ProcessCmdStoreInfo(const QJsonObject &jsonObj, QString &statusCode, QString &msg)
{
    QString operator_id, pos_id, store_id, business_date, metas_id, partner_id;

    QJsonObject store_info = jsonObj["store_info"].toObject();

    operator_id = store_info["operator_id"].toString();
    pos_id = store_info["pos_id"].toString();
    store_id = store_info["store_id"].toString();
    business_date = store_info["business_date"].toString();
    metas_id =store_info["mates_id"].toString();
    partner_id = store_info["partner_id"].toString();

    if(partner_id.isEmpty())
    {
        partner_id = store_id;
        store_id = pos_id.mid(0, pos_id.length()-4);
        pos_id = pos_id.right(4);
    }

    if(!operator_id.isEmpty() && !pos_id.isEmpty()
            && !store_id.isEmpty() && !business_date.isEmpty())
    {
        if(pos_id.compare(IniDataManger::Instance().GetStoreInfo().pos_id))
        {
            IniDataManger::StoreInfo storeInfo;
            storeInfo.business_date=business_date;
            storeInfo.mates_id=metas_id;
            storeInfo.operator_id=operator_id;
            storeInfo.partner_id=partner_id;
            storeInfo.pos_id=pos_id;
            storeInfo.store_id=store_id;
            WBillControl::GetInstance().SetStoreInfo(partner_id, store_id, operator_id, pos_id, business_date);
            IniDataManger::Instance().SetMates(metas_id.split('|'));
            IniDataManger::Instance().SetStoreInfo(storeInfo);
            emit getNewStoreInfo(jsonObj);
        }
        statusCode = "100";
        msg = "sucessful";
    }else
    {
        statusCode = "0";
        msg = "invalid store_info";
    }
}

void SInfoControl::_GetLocalStoreInfo()
{
    IniDataManger::StoreInfo storeInfo;
    storeInfo=IniDataManger::Instance().GetStoreInfo();
    if(!storeInfo.operator_id.isEmpty() && !storeInfo.pos_id.isEmpty()
       && !storeInfo.store_id.isEmpty() && !storeInfo.business_date.isEmpty() )
    {
        if(storeInfo.partner_id.isEmpty())
        {
            storeInfo.partner_id = storeInfo.store_id;
            storeInfo.store_id = storeInfo.pos_id.mid(0, storeInfo.pos_id.length()-4);
            storeInfo.pos_id = storeInfo.pos_id.right(4);
        }

        QJsonObject json,store;
        json.insert("fm_cmd","put_store_info");
        json.insert("fm_ver","1.0");
        store.insert("operator_id",storeInfo.operator_id);
        store.insert("pos_id",storeInfo.pos_id);
        store.insert("store_id",storeInfo.store_id);
        store.insert("partner_id",storeInfo.partner_id);
        store.insert("business_date",storeInfo.business_date);
        store.insert("mates_id",storeInfo.mates_id);
        json.insert("store_info",store);
        WBillControl::GetInstance().SetStoreInfo(storeInfo.partner_id, storeInfo.store_id,
                                                 storeInfo.operator_id, storeInfo.pos_id, storeInfo.business_date);
        IniDataManger::Instance().SetMates(storeInfo.mates_id.split('|'));
        IniDataManger::Instance().SetStoreInfo(storeInfo);
        emit getNewStoreInfo(json);
    }
}


void SInfoControl::run()
{
    //TODO测试可删
    QLOG_TRACE() << "emit info";
    _GetLocalStoreInfo();
    //emit getNewStoreInfo("1", "1", "pos_coco_CN9999", "20161215");
    m_tcpServer = new QTcpServer;
    if(m_tcpServer == NULL)
    {
        QLOG_TRACE() << "new tcpserver failed";
        return;
    }
    if(!m_tcpServer->listen(QHostAddress::LocalHost, m_port))
    {
        QString msg = QString("bind port(%1) failed, msg(%2)").arg(m_port).arg(m_tcpServer->errorString());
        QLOG_TRACE() << msg;
        emit listenFailed(msg);
        return;
    }
    QString statusCode, msg;
    QByteArray recvData;
    QJsonParseError jsonError;
    QJsonDocument jsonDoc;
    while(!m_bQuit)
    {
        if(!m_tcpServer->waitForNewConnection(200))
        {
            continue;
        }
        m_tcpSocket = m_tcpServer->nextPendingConnection();
        if(!m_tcpSocket->waitForReadyRead())
        {
            m_tcpSocket->close();
            continue;
        }
        recvData = m_tcpSocket->readAll();
        QLOG_TRACE() << QString("recv data(%1)").arg(QString(recvData));
        jsonDoc = QJsonDocument::fromJson(recvData, &jsonError);
        if(jsonError.error == QJsonParseError::NoError)
        {
            QJsonObject jsonObj = jsonDoc.object();
            QString fm_cmd = jsonObj["fm_cmd"].toString();
            if(!fm_cmd.compare("put_store_info"))
            {

                _ProcessCmdStoreInfo(jsonObj, statusCode, msg);
            }else
            {
                statusCode = "0";
                msg = "undefine cmd";
            }
        }else
        {
            statusCode = "0";
            msg = "invalid json";
        }
        //! 回应客户机
        QString reply = QString("{\"statusCode\":%1, \"msg\":\"%2\"}").arg(statusCode, msg);
        QLOG_TRACE() << QString("reply data(%1)").arg(reply);
        m_tcpSocket->write(reply.toUtf8());
        m_tcpSocket->waitForBytesWritten();
        m_tcpSocket->close();
        continue;
    }
    delete m_tcpServer;
    m_tcpServer = NULL;
    QLOG_TRACE() << "listenController thread exit";
}

