#include "valve.h"
#include "Modbus.h"
#include <QTimer>
#include <QElapsedTimer>

#include "ComStatistics.h"

static ComStatistics g_RelayControl_Statistics("RelayControl");

Valve::Valve(SerialUi* pSerial, int id)
{
    m_pSerial = pSerial;
    m_id = id;
}

bool Valve::check_crc(QByteArray data)
{
    int size = data.size();
    unsigned short crc1 =0, crc2= 0;

    unsigned char crc_h = data.at(size-2);
    unsigned char crc_l = data.at(size-1);

    crc1 = (crc_h <<8) |crc_l;
    crc2 = CRC16_MODBUS((unsigned char *)data.data(),data.size()-2);

     if(crc1 == crc2){
        return true;
     }else{
         return false;
     }
}

bool Valve::Open()
{
    QByteArray tx_buf;
    QElapsedTimer  timer;
    timer.start();

    char zero = 0x00;
    tx_buf.append(RELAY_ADDRESS);

    if(ALL_VALVE == m_id){
        tx_buf.append(0x0F);
        tx_buf.append(zero);
        tx_buf.append(zero);
        tx_buf.append(zero);
        tx_buf.append(0x04);
        tx_buf.append(0x01);
        tx_buf.append(0xFF);
    }else{
        tx_buf.append(0x05);
        tx_buf.append(zero);
        tx_buf.append(static_cast<char>(m_id));
        tx_buf.append(0xFF);
        tx_buf.append(zero);
    }


    unsigned short crc;

    crc=CRC16_MODBUS((unsigned char *)tx_buf.data(),tx_buf.size());

    tx_buf.append((crc>>8)&0xff);
    tx_buf.append(crc&0xff);

    g_RelayControl_Statistics.ReQuestCount_increase();
    QByteArray rx_buf;
    rx_buf = m_pSerial->serialWriteReponse(tx_buf);
    if(rx_buf.size() > 0){
        if(check_crc(rx_buf)){
            //qDebug("Valve_op ok  valve_id[%d], op[%d] ", id, op);
            g_RelayControl_Statistics.Update_Recvtime(timer.elapsed());
            return true;
        }else{
            qDebug("Valve Open crc failed  valve_id[%d]", m_id);
            g_RelayControl_Statistics.CrcErrorCount_increase();
            return false;
        }
    }else{
        qDebug("Valve Open no data received  valve_id[%d]", m_id);
        g_RelayControl_Statistics.TimeoutCount_increase();
        return false;
    }
}

bool Valve::Close()
{
    QByteArray tx_buf;
    QElapsedTimer  timer;
    timer.start();

    char zero = 0x00;
    tx_buf.append(RELAY_ADDRESS);

    if(ALL_VALVE == m_id){

        tx_buf.append(0x0F);
        tx_buf.append(zero);
        tx_buf.append(zero);
        tx_buf.append(zero);
        tx_buf.append(0x04);
        tx_buf.append(0x01);
        tx_buf.append(zero);
    }else{
        tx_buf.append(0x05);
        tx_buf.append(zero);
        tx_buf.append(static_cast<char>(m_id));
        tx_buf.append(zero);
        tx_buf.append(zero);
    }

    unsigned short crc;
    crc=CRC16_MODBUS((unsigned char *)tx_buf.data(), tx_buf.size());

    tx_buf.append((crc>>8)&0xff);
    tx_buf.append(crc&0xff);

    g_RelayControl_Statistics.ReQuestCount_increase();
    QByteArray rx_buf;
    rx_buf = m_pSerial->serialWriteReponse(tx_buf);
    if(rx_buf.size() > 0){

        if(check_crc(rx_buf)){
            g_RelayControl_Statistics.Update_Recvtime(timer.elapsed());
            return true;
        }else{
            qDebug("Valve close crc failed  valve_id[%d]", m_id);
            g_RelayControl_Statistics.CrcErrorCount_increase();
            return false;
        }
    }else{
        qDebug("Valve close no data received  valve_id[%d]", m_id);
        g_RelayControl_Statistics.TimeoutCount_increase();
        return false;
    }
}

bool Valve::ReadStatus()
{
    QByteArray tx_buf;
    QElapsedTimer  timer;
    timer.start();

    char zero = 0x00;
    tx_buf.append(RELAY_ADDRESS);

    tx_buf.append(0x04);
    tx_buf.append(0x03);
    tx_buf.append(0xE8);
    tx_buf.append(zero);
    tx_buf.append(0x14);

    unsigned short crc;
    crc=CRC16_MODBUS((unsigned char *)tx_buf.data(), tx_buf.size());

    tx_buf.append((crc>>8)&0xff);
    tx_buf.append(crc&0xff);

    g_RelayControl_Statistics.ReQuestCount_increase();

    QByteArray rx_buf;
    rx_buf = m_pSerial->serialWriteReponse(tx_buf);
    if(rx_buf.size() > 0){

        //for(int i=0; i<rx_buf.size(); i++){
        //    qDebug("ReadStatus rx_buf[%d]: 0x%X", i, rx_buf.at(i));
        //}

        if(check_crc(rx_buf)){
            g_RelayControl_Statistics.Update_Recvtime(timer.elapsed());
            return true;
        }else{
            qDebug("Valve ReadStatus crc failed  valve_id[%d]", m_id);
            g_RelayControl_Statistics.CrcErrorCount_increase();
            return false;
        }
    }else{
        qDebug("Valve ReadStatus no data received  valve_id[%d]", m_id);
        g_RelayControl_Statistics.TimeoutCount_increase();
        return false;
    }
}

void Valve::Dump_Statistics(QString file_path)
{
    g_RelayControl_Statistics.Save2File(file_path);
}
