#include "LTENetworkInterface.h"
#include "NetworkProtocol.h"
#include "SIM7080GInterface.h"
#include "timer.h"
#include "ChaletPowerRelay.h"
#include "HarakiriRelay.h"
#include "BatteryMonitor.h"
#include "LedLightCtrl.h"
#include "TemperatureSensor.h"
#include "SPI_Flash.h"
#include "FlashMapping.h"
#include "LoraWatchdog.h"
#include "versionbuild.h"
#include "WiFiCtrl.h"
#include "BoardCfg.h"

int mLTENWISMState;
static const char mFirmwareVersion[15] = VERSIONNUMBER;
#define LORA_CHALET_STATUS_CUR_SENSOR_MASK 0x02
#define LORA_CHALET_STATUS_POWER_RELAY_MASK 0x01

unsigned int mLTETotalMasterNbRequests = 0;

void LTENetworkInterfaceInit()
{
    ProtocolInit(NETWORK_PROTOCOL_USER_LTE);
    
    mLTENWISMState = LTE_NWI_INIT_STATE;
}

void ExecuteLTEMasterCommand(int SenderID, int Command, unsigned char *Data, int DataSize)
{
    KickLoraWatchdog();
//    ChaletPowerRelayKickTimer();
    mLTETotalMasterNbRequests++;
//    LTE_MODULE_RX_LED_PIN = LED_OFF;
    switch(SenderID)
    {
        case ID_MASTER:
        {
            switch(Command)
            {
                case CHALET_INTERFACE_ACK:
                {
                    break;
                }
                case CHALET_GENERAL_STATUS_REQUEST:
                {
//                    float FloatVoltage = GetBatteryVoltage(1);
////                    float FloatTemperature = TempSensorGetTemp();
//                    unsigned int BattVoltage = *((int*)&FloatVoltage);
//                    unsigned int Temperature  = *((int*)&FloatTemperature);
//                    int SolarPanelCurrent = GetSolarPanelCurrent();
//                    int SOC = GetBatterySOC();
//                    
//                    char GeneralStatus = 0;
//                    char ChaletStatus[18];
//                    
//                    if(GetChaletPowerRelayState() == CHALET_POWER_RELAY_ON_STATE)
//                    {
//                        GeneralStatus |= LORA_CHALET_STATUS_POWER_RELAY_MASK;
//                    }
//                    if(GetCurrentModuleOK() == true)
//                    {
//                        GeneralStatus |= LORA_CHALET_STATUS_CUR_SENSOR_MASK;
//                    }
//                    
//                    ChaletStatus[0] = GeneralStatus;    //General Status
//                    ChaletStatus[1] = GetWiFiSate();    //Wifi Module state
//                    
//                    ChaletStatus[2] = (char)(BattVoltage & 0x000000FF);    //Battery Voltage 1
//                    BattVoltage >>= 8;
//                    ChaletStatus[3] = (char)(BattVoltage & 0x000000FF);    //Battery Voltage 2
//                    BattVoltage >>= 8;
//                    ChaletStatus[4] = (char)(BattVoltage & 0x000000FF);    //Battery Voltage 3
//                    BattVoltage >>= 8;
//                    ChaletStatus[5] = (char)(BattVoltage & 0x000000FF);    //Battery Voltage 4
//                    
//                    ChaletStatus[6] = (char)(SolarPanelCurrent & 0x000000FF);    //Solar panel Current 1
//                    SolarPanelCurrent >>= 8;
//                    ChaletStatus[7] = (char)(SolarPanelCurrent & 0x000000FF);    //Solar panel Current 2
//                    
//                    ChaletStatus[8] = (char)(SOC & 0x000000FF);    //Battery SOC 1
//                    SolarPanelCurrent >>= 8;    
//                    ChaletStatus[9] = (char)(SolarPanelCurrent & 0x000000FF);  //Battery SOC 2
//                    
//                    ChaletStatus[10] = (char)(Temperature & 0x000000FF);    //Temperature 1
//                    Temperature >>= 8;
//                    ChaletStatus[11] = (char)(Temperature & 0x000000FF);    //Temperature 2
//                    Temperature >>= 8;
//                    ChaletStatus[12] = (char)(Temperature & 0x000000FF);    //BTemperature 3
//                    Temperature >>= 8;
//                    ChaletStatus[13] = (char)(Temperature & 0x000000FF);    //Temperature 4
//                    
//                    int tmp = mLTETotalMasterNbRequests;
//                    ChaletStatus[14] = (char)(mLTETotalMasterNbRequests & 0x000000FF);    //Total Nb Requests 1
//                    mLTETotalMasterNbRequests >>= 8;
//                    ChaletStatus[15] = (char)(mLTETotalMasterNbRequests & 0x000000FF);    //Total Nb Requests 2
//                    mLTETotalMasterNbRequests >>= 8;
//                    ChaletStatus[16] = (char)(mLTETotalMasterNbRequests & 0x000000FF);    //Total Nb Requests 3
//                    mLTETotalMasterNbRequests >>= 8;
//                    ChaletStatus[17] = (char)(mLTETotalMasterNbRequests & 0x000000FF);    //Total Nb Requests 4
//                    mLTETotalMasterNbRequests = tmp;
//                    
//                    
//                    SendLTENetworkCommand(CHALET_GENERAL_STATUS_RESPONSE,ChaletStatus,18);
//                    
//                    HEARTBEAT_LED_1_PIN = ~HEARTBEAT_LED_1_PIN;
                    
                    break;
                }
                case CHALET_AC_POWER_STATE_STATUS_REQUEST:
                {
//                    char PowerStatus = GetChaletPowerRelayState();
//                    SendLTENetworkCommand(CHALET_AC_POWER_STATE_STATUS_RESPONSE,&PowerStatus,1);
                    break;
                }
                case CHALET_AC_POWER_SET_STATE_REQUEST:
                {
//                    char response = CHALET_POWER_RELAY_UNKNOWN_STATE;
//                    if(Data[0] == CHALET_POWER_RELAY_OFF_STATE)
//                    {
//                        ChaletPowerRelayTurnOff();
//                        response = CHALET_POWER_RELAY_OFF_STATE;
//                    }
//                    else if(Data[0] == CHALET_POWER_RELAY_ON_STATE)
//                    {
//                        ChaletPowerRelayTurnOn();
//                        response = CHALET_POWER_RELAY_ON_STATE;
//                    }
//                    else
//                    {
//                        //invalid state requested.... don't do anything
//                        response = CHALET_POWER_RELAY_UNKNOWN_STATE;
//                    }
//                    
//                    SendLTENetworkCommand(CHALET_AC_POWER_SET_STATE_RESPONSE,&response,1);
//                    
                    break;
                }
                case CHALET_BATTERY_VOLTAGE_REQUEST:
                {
                    
                    break;
                }
                case CHALET_WIFI_STATUS_REQUEST:
                {
                    char response[5];
                    uint32 IPAddress = GetCurIPAddress();
                    
                    response[0] = GetWiFiSate();    //Wifi Module state
                    response[1] = IPV4_BYTE(IPAddress,0);
                    response[2] = IPV4_BYTE(IPAddress,1);
                    response[3] = IPV4_BYTE(IPAddress,2);
                    response[4] = IPV4_BYTE(IPAddress,3);
                    SendLTENetworkCommand(CHALET_WIFI_STATUS_RESPONSE,(unsigned char*)&response,5);
                    break;
                }        
                case CHALET_WIFI_SET_STATE_REQUEST:
                {
                    char response = WIFI_UNKNOWN_STATE;
                    if(Data[0] == 0)
                    {
                        TurnOFFWiFi();
                        response = 0;
                    }
                    else if(Data[0] == 1)
                    {
                        if(GetWiFiSate() != WIFI_CONNECTED_STATE)
                        {
                            InitWiFi();
                            response = GetWiFiSate();
                        }
                        else
                        {
                            response = 1;
                        }
                    }
                    else
                    {
                        //invalid state requested.... don't do anything
                        response = WIFI_UNKNOWN_STATE;
                    }
                    
                    SendLTENetworkCommand(CHALET_WIFI_SET_STATE_RESPONSE,&response,1);
                    break;
                }
                case CHALET_DO_HARAKIRI_REQUEST:
                {
//                    char response;
//                    if(Data[0] == 0xBA &&
//                            Data[1] == 0xAD &&
//                            Data[2] == 0xBE &&
//                            Data[3] == 0xEF)
//                    {
//                        //Magic word is OK... let's suicide...
//                        response = 0x01;
//                        //First, send an ACK to master (this is blocking so it's OK)
//                        SendLTENetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&response,1);
//                        HarakiriRelayTurnOff();
//                    }
//                    else
//                    {
//                        response = 0x00;
//                        SendLTENetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&response,1);
//                    }
                    break;
                }
                case CHALET_REBOOT_CPU_REQUEST:
                {
                    char response;
                    if(Data[0] == 0xBA &&
                            Data[1] == 0xAD &&
                            Data[2] == 0xCA &&
                            Data[3] == 0xFE)
                    {
                        //Magic word is OK... let's reboot...
                        response = 0x01;
                        //First, send an ACK to master (this is blocking so it's OK)
                        SendLTENetworkCommand(CHALET_REBOOT_CPU_RESPONSE,&response,1);
                        Sleep(100);
                        TurnOFFWiFi();
                        Sleep(100);
                        SoftReset();
                    }
                    else
                    {
                        response = 0x00;
                        SendLTENetworkCommand(CHALET_DO_HARAKIRI_CONFIRMATION,&response,1);
                    }
                    break;
                }
                case CHALET_GET_STORED_WIFI_SETTINGS_REQUEST:
                {
                    char response[140];
                    char WifiDataSize;
                    SPIFlashReadBuffer(response,11,FLASH_WIFI_IP_ADDRESS);
                    WifiDataSize = 11 + response[9] + response[10];
                    if(WifiDataSize > 140)
                        break;
                    SPIFlashReadBuffer(response,WifiDataSize,FLASH_WIFI_IP_ADDRESS);
                    SendLTENetworkCommand(CHALET_GET_STORED_WIFI_SETTINGS_RESPONSE,response,WifiDataSize);
                    break;
                }
                case CHALET_SET_STORED_WIFI_SETTINGS_REQUEST:
                {
                    char response = 0;
                    if(SPIFlashWriteBuffer(Data,DataSize,FLASH_WIFI_IP_ADDRESS) == 1)
                    {
                        response = 1;
                    }
                    
                    SendLTENetworkCommand(CHALET_SET_STORED_WIFI_SETTINGS_RESPONSE,&response,1);
                    break;
                }
                case CHALET_GET_FIRMWARE_VERSION_REQUEST:
                {
                    SendLTENetworkCommand(CHALET_GET_FIRMWARE_VERSION_RESPONSE,(unsigned char*)mFirmwareVersion,15);
                    break;
                }
                case CHALET_CLEAR_COMMS_STATISTICS_REQUEST:
                {
                    char response = 1;
                    mLTETotalMasterNbRequests = 0;
                    SendLTENetworkCommand(CHALET_CLEAR_COMMS_STATISTICS_RESPONSE,&response,1);
                    break;
                }
                case ETH_NETWK_DEVICE_INFO_REQUEST:
                {
                    char data[2];
                    data[0] = ID_CHALET_DEVICE;
                    data[1] = MY_DEVICE_ADDRESS;
                    int PayloadSize;
                    unsigned char *response = ProtocolGetFrame(ID_MASTER,MASTER_ADDRESS,ID_ETHERNET_VIRTUAL,ETH_NETWK_DEVICE_INFO_RESPONSE, data,2,0, &PayloadSize);
                    LTESendDataToMaster((char*)response,PayloadSize);
                    
                    break;
                }
                case ETH_NETWK_SET_DEVICE_INFO_ACK:
                {
                    LTENetworInterfaceExecSM(LTE_NWI_MASTER_CONNECTED_EVENT);
                    break;
                }
                case ETH_NETWK_CONNECTION_REFUSED:
                {
                    //TODO: reset the TCP module to retry connection???
                    break;
                }
            }
            break;
        }
        default:
        {
            break;
        }
    }
}

void TickLTENetworkInterface()
{
    LTENetworInterfaceExecSM(LTE_NWI_TICK_EVENT);
}

void LTENetworInterfaceExecSM(int Event)
{
    switch(mLTENWISMState)
    {
        case LTE_NWI_INIT_STATE:
        {
            mLTENWISMState = LTE_NWI_CONNECT_TO_MASTER_STATE;
            TimerStart(LTE_NWI_TIMER,LTE_NWI_MASTER_CONNECT_POLL_INTERVAL);
            break;
        }
        case LTE_NWI_WAIT_FOR_LTE_STATE:
        {
            //Not necessary... master will init handshake on TCP connection....
            break;
        }
        case LTE_NWI_CONNECT_TO_MASTER_STATE:   //Here we wait for the master to initiate the handshake after a TCP connection
        {
            if(Event == LTE_NWI_MASTER_CONNECTED_EVENT)
            {
                mLTENWISMState = LTE_NWI_OPERATE_STATE;
            }
            break;
        }
        case LTE_NWI_OPERATE_STATE:
        {
            if(Event == LTE_NWI_TICK_EVENT)
            {
                
            }
            break;
        }
    }
}

void SendLTENetworkCommand(int Command, unsigned char *Data, unsigned int DataSize)
{
    unsigned char *Payload;
    unsigned int PayloadSize;
    Payload = ProtocolGetFrame(ID_MASTER,MASTER_ADDRESS,ID_CHALET_DEVICE,Command,Data,DataSize,0,&PayloadSize);
    LTESendDataToMaster(Payload,PayloadSize);
}