#include "EthernetNetworkServer.h"
#include "MasterCtrl.h"
#include "EthernetNetworkCommIF.h"


CEthernetNetworkServer::CEthernetNetworkServer()
{
    mProgramHandle = 0;
    mDevicesMgrHandle = 0;

    SetManualPacketReset(true);
}

CEthernetNetworkServer::~CEthernetNetworkServer()
{
    CloseServer();
}

int CEthernetNetworkServer::StartServer(int port)
{
    mEthernetNetworkServer = new QTcpServer;
    connect(mEthernetNetworkServer,SIGNAL(newConnection()),this,SLOT(EthernetNetworkServerConnected()));
    if(mEthernetNetworkServer->listen(QHostAddress::Any,port) == true)
    {
        qDebug("Ethernet Network Server listening on port %d", port);
        return RET_OK;
    }
    else
    {
        return RET_ERROR;
    }
}

int CEthernetNetworkServer::CloseServer()
{
    mEthernetNetworkServer->close();
 //   mEthernetNetworkServer->deleteLater();
    qDebug("Ethernet Network server closed");

    return RET_OK;
}

void CEthernetNetworkServer::EthernetNetworkServerConnected()
{
    qDebug("Device Connected");
    QTcpSocket *EthernetDeviceSocket;

    EthernetDeviceSocket = mEthernetNetworkServer->nextPendingConnection();
   // CEthernetDeviceConnection *NewConnection = new CEthernetDeviceConnection;
  //  NewConnection->mConnectionSocket = EthernetDeviceSocket;
    // mEthernetDeviceConnections.append(NewConnection);
    if(EthernetDeviceSocket != 0)
    {

        connect(EthernetDeviceSocket,SIGNAL(readyRead()),this,SLOT(DeviceSocketDataAvail()));
        connect(EthernetDeviceSocket,SIGNAL(disconnected()),this,SLOT(DeviceSocketDisconnected()));

        //request device info...
        QByteArray Frame = GetTxPacket((unsigned char)ETH_NETWK_DEVICE_INFO_REQUEST,0,0,0,BROADCAST_VALUE,(unsigned char)ID_ETHERNET_VIRTUAL);
        EthernetDeviceSocket->write(Frame);
    }
}

//CEthernetDeviceConnection * CEthernetNetworkServer::FindConnection(QTcpSocket *Socket)
//{
//    for(int i = 0; i < mEthernetDeviceConnections.size(); i++)
//    {
//        if(Socket == mEthernetDeviceConnections.at(i)->mConnectionSocket)
//        {
//            return mEthernetDeviceConnections.at(i);
//        }
//    }

//    return 0;
//}

//int CEthernetNetworkServer::FindConnection(CEthernetDeviceConnection* Connection)
//{
//    for(int i = 0; i < mEthernetDeviceConnections.size(); i++)
//    {
//        if(Connection == mEthernetDeviceConnections.at(i))
//        {
//            return i;
//        }
//    }

//    return -1;
//}

void CEthernetNetworkServer::DeviceSocketDataAvail()
{
    QTcpSocket *DeviceSocket = (QTcpSocket*)QObject::sender();
    QByteArray Packet = DeviceSocket->readAll();

    //CEthernetDeviceConnection *DeviceConnection = FindConnection(DeviceSocket);


    int ret = AnalyzeRxBuffer(Packet);


    bool CloseSocket = false;
//    if(DeviceConnection == 0)
//    {
//        qDebug("Rx from unknown socket!");
//        CloseSocket = true;
//    }

    switch(ret)
    {
        case PROTOCOL_RET_OK_PACKET_COMPLETE:
        {
            if(ProtocolGetSenderID() == ID_ETHERNET_VIRTUAL)
            {
                if(ProtocolGetCmd() == ETH_NETWK_DEVICE_INFO_RESPONSE)
                {

                    CEthernetNetworkCommIF *NetworkIF = new CEthernetNetworkCommIF(DeviceSocket);
                    QByteArray Data = ProtocolGetData();
                    char DeviceID,DeviceAddress;

                    DeviceID = Data.at(0);
                    DeviceAddress = Data.at(1);

                    int Result = RES_CREATION_FAILED;
                    switch(DeviceID)
                    {
                        case ID_SMS_CLIENT:
                        {
                            if(mDevicesMgrHandle->CreateNewSMSDevice(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
                            {
                                Result = RES_CREATION_SUCCESS;
                                qDebug("Created new SMS device");
                            }
                            else
                            {
                                Result = RES_CREATION_FAILED;
                                qDebug("Could not create SMS device in ethernet server");
                            }
                            break;
                        }
                        case ID_SPRINKLER_DEVICE:
                        {
                            if(mDevicesMgrHandle->CreateNewSprinklerDevice(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
                            {
                                Result = RES_CREATION_SUCCESS;
                                qDebug("Created new Sprinkler device");
                            }
                            else
                            {
                                Result = RES_CREATION_FAILED;
                                qDebug("Could not create Sprinkler device in ethernet server");
                            }
                            break;
                        }
                        case ID_SPRINKLER_INTERFACE:
                        {
                            if(mDevicesMgrHandle->CreateNewSprinklerInterface(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
                            {
                                Result = RES_CREATION_SUCCESS;
                                qDebug("Created new Sprinkler Interface");
                            }
                            else
                            {
                                Result = RES_CREATION_FAILED;
                                qDebug("Could not create Sprinkler Interface in ethernet server");
                            }
                            break;
                        }
                        case ID_AVRECEIVER_INTERFACE:
                        {
                            if(mDevicesMgrHandle->CreateNewAvReceiverInterface(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
                            {
                                Result = RES_CREATION_SUCCESS;
                                qDebug("Created new AV Receiver Interface");
                            }
                            else
                            {
                                Result = RES_CREATION_FAILED;
                                qDebug("Could not create AV Receiver Interface in ethernet server");
                            }
                            break;
                        }
                        case ID_CHALET_INTERFACE:
                        {
                            if(mDevicesMgrHandle->CreateNewChaletInterface(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
                            {
                                Result = RES_CREATION_SUCCESS;
                                qDebug("Created new Chalet Interface");
                            }
                            else
                            {
                                Result = RES_CREATION_FAILED;
                                qDebug("Could not create Chalet Interface in ethernet server");
                            }
                            break;
                        }
                        case ID_ISPINDEL_INTERFACE:
                        {
                            if(mDevicesMgrHandle->CreateNewIspindleInterface(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
                            {
                                Result = RES_CREATION_SUCCESS;
                                qDebug("Created new Ispindel Interface");
                            }
                            else
                            {
                                Result = RES_CREATION_FAILED;
                                qDebug("Could not create Ispindel Interface in ethernet server");
                            }
                            break;
                        }
                        case ID_LORA_INTERFACE_INTERFACE:
                        {
                            if(mDevicesMgrHandle->CreateNewLoraInterfaceInterface(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
                            {
                                Result = RES_CREATION_SUCCESS;
                                qDebug("Created new Lora Interface Interface in ethernet server");
                            }
                            else
                            {
                                Result = RES_CREATION_FAILED;
                                qDebug("Could not create Lora Interface Interface in ethernet server");
                            }
                            break;
                        }
                        case ID_CHALET_DEVICE:
                        {
                            if(mDevicesMgrHandle->BindNetworkChaletDevice(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
                            {
                                Result = RES_CREATION_SUCCESS;
                                qDebug("Created new Ethernet (LTE) Chalet Device in ethernet server");
                            }
                            else
                            {
                                Result = RES_CREATION_FAILED;
                                qDebug("Could not create Ethernet (LTE) Chalet Device in ethernet server");
                            }
                            break;
                        }
                        case ID_AVRECEIVER_CONSOLE_INTERFACE:
                        {
                            if(mDevicesMgrHandle->CreateNewAVReceiverConsoleInterface(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
                            {
                                Result = RES_CREATION_SUCCESS;
                                qDebug("Created new AV Receiver Console Interface");
                            }
                            else
                            {
                                Result = RES_CREATION_FAILED;
                                qDebug("Could not create AV Receiver Interface in ethernet server");
                            }
                            break;
                        }
                        default:
                        {
                            Result = RES_CREATION_UNKNOWN_DEVICE;
                            qDebug("Invalid DevicesMgrHandle in ethernet server");
                            CloseSocket = true;
                            break;
                        }
                    }

                    if(Result == RES_CREATION_SUCCESS)
                    {
                        //All OK.

                        //Redirect signals.
                        DeviceSocket->disconnect();
                        connect(DeviceSocket,SIGNAL(readyRead()),NetworkIF,SLOT(SocketDataAvailable()));
                        connect(DeviceSocket,SIGNAL(disconnected()),NetworkIF,SLOT(SocketDisconnected()));
                        connect(NetworkIF,SIGNAL(EthernetInterfaceSocketDisconnected(CNetworkDevice*)),mDevicesMgrHandle,SLOT(EthernetNetworkDeviceDisconnected(CNetworkDevice*)));

                        //Inform device that it is connected
                        QByteArray Frame = GetTxPacket((unsigned char)ETH_NETWK_SET_DEVICE_INFO_ACK,0,0,0,DeviceAddress,(unsigned char)ID_ETHERNET_VIRTUAL);
                        DeviceSocket->write(Frame);
                    }
                    else if(Result == RES_CREATION_FAILED)
                    {
                        QByteArray Frame = GetTxPacket((unsigned char)ETH_NETWK_CONNECTION_REFUSED,0,0,0,DeviceAddress,(unsigned char)ID_ETHERNET_VIRTUAL);
                        DeviceSocket->write(Frame);
                        CloseSocket = true;
                    }


//                    if(DeviceID == ID_SMS_CLIENT)
//                    {
//                        if(mDevicesMgrHandle != 0)
//                        {
//                            if(mDevicesMgrHandle->CreateNewSMSDevice(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
//                            {
//                                //All OK.

//                                //Redirect signals.
//                                DeviceSocket->disconnect();
//                             //   disconnect(DeviceSocket,SIGNAL(readyRead()),this,SLOT(DeviceSocketDataAvail()));
//                                connect(DeviceSocket,SIGNAL(readyRead()),NetworkIF,SLOT(SocketDataAvailable()));
//                                connect(DeviceSocket,SIGNAL(disconnected()),NetworkIF,SLOT(SocketDisconnected()));
//                                connect(NetworkIF,SIGNAL(EthernetInterfaceSocketDisconnected(CNetworkDevice*)),mDevicesMgrHandle,SLOT(EthernetNetworkDeviceDisconnected(CNetworkDevice*)));

//                                //Inform device that it is connected
//                                QByteArray Frame = GetTxPacket((unsigned char)ETH_NETWK_SET_DEVICE_INFO_ACK,0,0,0,DeviceAddress,(unsigned char)ID_ETHERNET_VIRTUAL);
//                                DeviceSocket->write(Frame);
//                                qDebug("Created new SMS device");
//                            }
//                            else
//                            {
//                                qDebug("Could not create SMS device in ethernet server");
//                                QByteArray Frame = GetTxPacket((unsigned char)ETH_NETWK_CONNECTION_REFUSED,0,0,0,DeviceAddress,(unsigned char)ID_ETHERNET_VIRTUAL);
//                                DeviceSocket->write(Frame);
//                                CloseSocket = true;
//                            }
//                        }
//                        else
//                        {
//                            qDebug("Invalid DevicesMgrHandle in ethernet server");
//                            CloseSocket = true;
//                        }
//                    }
//                    else if(DeviceID == ID_SPRINKLER_DEVICE)
//                    {
//                        if(mDevicesMgrHandle != 0)
//                        {
//                            if(mDevicesMgrHandle->CreateNewSprinklerDevice(DeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
//                            {
//                                //All OK.

//                                //Redirect signals.
//                                DeviceSocket->disconnect();
//                             //   disconnect(DeviceSocket,SIGNAL(readyRead()),this,SLOT(DeviceSocketDataAvail()));
//                                connect(DeviceSocket,SIGNAL(readyRead()),NetworkIF,SLOT(SocketDataAvailable()));
//                                connect(DeviceSocket,SIGNAL(disconnected()),NetworkIF,SLOT(SocketDisconnected()));
//                                connect(NetworkIF,SIGNAL(EthernetInterfaceSocketDisconnected(CNetworkDevice*)),mDevicesMgrHandle,SLOT(EthernetNetworkDeviceDisconnected(CNetworkDevice*)));

//                                //Inform device that it is connected
//                                QByteArray Frame = GetTxPacket((unsigned char)ETH_NETWK_SET_DEVICE_INFO_ACK,0,0,0,DeviceAddress,(unsigned char)ID_ETHERNET_VIRTUAL);
//                                DeviceSocket->write(Frame);
//                                qDebug("Created new Sprinkler device");
//                            }
//                            else
//                            {
//                                qDebug("Could not create Sprinkler device in ethernet server");
//                                QByteArray Frame = GetTxPacket((unsigned char)ETH_NETWK_CONNECTION_REFUSED,0,0,0,DeviceAddress,(unsigned char)ID_ETHERNET_VIRTUAL);
//                                DeviceSocket->write(Frame);
//                                CloseSocket = true;
//                            }
//                        }
//                        else
//                        {
//                            qDebug("Invalid DevicesMgrHandle in ethernet server");
//                            CloseSocket = true;
//                        }
//                    }

//                    if(IsDeviceRegistered(DeviceID) == true)
//                    {
//                        DeviceConnection->mConnectedDevice->mDeviceID = (int)DeviceID;
//                        DeviceConnection->mConnectedDevice->mDeviceAddress = (int)DeviceAddress;
//                    }
//                    else
//                    {
//                        qDebug("Rx device info from unregistered device");
//                        CloseSocket = true;
//                    }
                }

            }
            else
            {
                qDebug("Received protocol data in ethernet server");
//                if(DeviceConnection != 0)
//                {
//                    DeviceConnection->mConnectedDevice->NewDeviceFrameReceived(ProtocolGetSenderID(),ProtocolGetSenderAddress(),ProtocolGetCmd(),ProtocolGetDataSize(),ProtocolGetData());
//                    PrepareForNewPacket();
//                }
//                else
//                {
//                    qDebug("Rx from invalid device connection pointer!");
//                    CloseSocket = true;
//                }
            }
            PrepareForNewPacket();
            break;
        }
        case PROTOCOL_RET_OK_PACKET_INCOMPLETE:
        {
            break;
        }
        case PROTOCOL_RET_ERROR_BAD_HEADER:
        {
            break;
        }
        case PROTOCOL_RET_ERROR_INVALID_TARGET_DEVICE:
        {
            qDebug("Bad target device received on Ethernet server");
            PrepareForNewPacket();
            break;
        }
        case PROTOCOL_RET_ERROR_INVALID_TARGET_ADDRESS:
        {
            qDebug("Bad target address received on Ethernet server");
            PrepareForNewPacket();
            break;
        }
        case PROTOCOL_RET_ERROR_BAD_CRC:
        {
            qDebug("Bad target CRC on Ethernet server");
            PrepareForNewPacket();
            break;
        }
        case PROTOCOL_RET_ERROR_SM_LOGIC:
        {
            qDebug("LOGIC ERROR!!! on Ethernet server protocol");
            PrepareForNewPacket();
            break;
        }
        case PROTOCOL_RET_ERROR_EMPTY_BUFFER:
        {
            qDebug("Trying to analyze an empty buffer on Ethernet server");
            PrepareForNewPacket();
        }
    }

    if(CloseSocket == true)
    {
    //    if(CloseConnection(DeviceConnection) != RET_OK)
        {
            DeviceSocket->close();
            //delete DeviceSocket;
        }
        PrepareForNewPacket();
    }


}

void CEthernetNetworkServer::DeviceSocketDisconnected()
{
    qDebug("Socket disconnected...");
}

//int CEthernetNetworkServer::CloseConnection(CEthernetDeviceConnection *Connection)
//{
//    if(Connection != 0)
//    {
//        int index = FindConnection(Connection);
//        if(index != -1)
//        {
//            Connection->mConnectionSocket->close();
//            mEthernetDeviceConnections.removeAt(index);
//            delete Connection;
//            return RET_OK;
//        }
//    }

//    return RET_ERROR;
//}

//int CEthernetNetworkServer::RegisterNewDevice(CNetworkDevice *Device)
//{
//    if(IsDeviceRegistered(Device->GetDeviceID()))
//    {
//        qDebug("Device already registered");
//        return RET_ERROR;
//    }

//    //mNetworkDevices.append(Device);
//    return RET_OK;
//}

//bool CEthernetNetworkServer::IsDeviceRegistered(int DeviceID)
//{
//    for(int i = 0; i < mNetworkDevices.size(); i++)
//    {
//        if(mNetworkDevices.at(i)->GetDeviceID() == DeviceID)
//        {
//            return true;
//        }
//    }

//    return true;
//}
int CEthernetNetworkServer::NewFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data)
{
    Q_UNUSED(DeviceAddress)
    Q_UNUSED(DataSize)
    Q_UNUSED(Data)
    Q_UNUSED(MessageID)
    Q_UNUSED(DeviceID)

//    if(DeviceID == ID_ETHERNET_VIRTUAL)
//    {
//        if(MessageID == ETH_NETWK_DEVICE_INFO_RESPONSE)
//        {

//            CEthernetNetworkCommIF *NetworkIF = new CEthernetNetworkCommIF(DeviceSocket);
//            QByteArray Data = ProtocolGetData();
//            char DeviceID,DeviceAddress;

//            RemoteDeviceID = Data.at(0);
//            RemoteDeviceAddress = Data.at(1);

//            if(RemoteDeviceID == ID_SMS_CLIENT)
//            {
//                if(mDevicesMgrHandle != 0)
//                {
//                    if(mDevicesMgrHandle->CreateNewSMSDevice(RemoteDeviceAddress,(CAbstractNetworkCommIF*)NetworkIF) == RET_OK)
//                    {
//                        //All OK.

//                        //Redirect signals.
//                        DeviceSocket->disconnect();
//                     //   disconnect(DeviceSocket,SIGNAL(readyRead()),this,SLOT(DeviceSocketDataAvail()));
//                        connect(DeviceSocket,SIGNAL(readyRead()),NetworkIF,SLOT(SocketDataAvailable()));
//                        connect(DeviceSocket,SIGNAL(disconnected()),NetworkIF,SLOT(SocketDisconnected()));
//                        connect(NetworkIF,SIGNAL(EthernetInterfaceSocketDisconnected(CNetworkDevice*)),mDevicesMgrHandle,SLOT(EthernetNetworkDeviceDisconnected(CNetworkDevice*)));

//                        //Inform device that it is connected
//                        QByteArray Frame = GetTxPacket((unsigned char)ETH_NETWK_SET_DEVICE_INFO_ACK,0,0,0,RemoteDeviceAddress,(unsigned char)ID_ETHERNET_VIRTUAL);
//                        DeviceSocket->write(Frame);
//                    }
//                    else
//                    {
//                        qDebug("Could not create SMS device in ethernet server");
//                        QByteArray Frame = GetTxPacket((unsigned char)ETH_NETWK_CONNECTION_REFUSED,0,0,0,RemoteDeviceAddress,(unsigned char)ID_ETHERNET_VIRTUAL);
//                        DeviceSocket->write(Frame);
//                        CloseSocket = true;
//                    }
//                }
//                else
//                {
//                    qDebug("Invalid DevicesMgrHandle in ethernet server");
//                    CloseSocket = true;
//                }
//            }

////                    if(IsDeviceRegistered(DeviceID) == true)
////                    {
////                        DeviceConnection->mConnectedDevice->mDeviceID = (int)DeviceID;
////                        DeviceConnection->mConnectedDevice->mDeviceAddress = (int)DeviceAddress;
////                    }
////                    else
////                    {
////                        qDebug("Rx device info from unregistered device");
////                        CloseSocket = true;
////                    }
//        }

//    }
//    else
//    {
//        qDebug("Received protocol data in ethernet server");
////                if(DeviceConnection != 0)
////                {
////                    DeviceConnection->mConnectedDevice->NewDeviceFrameReceived(ProtocolGetSenderID(),ProtocolGetSenderAddress(),ProtocolGetCmd(),ProtocolGetDataSize(),ProtocolGetData());
////                    PrepareForNewPacket();
////                }
////                else
////                {
////                    qDebug("Rx from invalid device connection pointer!");
////                    CloseSocket = true;
////                }
//    }

    return RET_OK;
}
