#include "lora_net.h"

LoRa_E220 e220ttl(GPIO_LORA_TX, GPIO_LORA_RX, GPIO_LORA_AUX, 3, 4); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1

void printParameters(struct Configuration configuration);
void printModuleInformation(struct ModuleInformation moduleInformation);

bool InitLoRa(void (*MPinHelper)(int, int))
{
    bool returnval;

    e220ttl.setMPins = MPinHelper;
    returnval = e220ttl.begin();

    if (returnval == true)
    {
        ResponseStructContainer c;
        c = e220ttl.getConfiguration();
        // It's important get configuration pointer before all other operation
        Configuration configuration = *(Configuration *)c.data;
        Serial.println(c.status.getResponseDescription());
        Serial.println(c.status.code);

        ResponseStructContainer cMi;
        cMi = e220ttl.getModuleInformation();
        // It's important get information pointer before all other operation
        // ModuleInformation mi = *(ModuleInformation *)cMi.data;

        Serial.println(cMi.status.getResponseDescription());
        Serial.println(cMi.status.code);

        //	----------------------- DEFAULT TRANSPARENT WITH RSSI -----------------------
        configuration.ADDL = 0x02;
        configuration.ADDH = 0x00;

        configuration.CHAN = 23;

        configuration.SPED.uartBaudRate = UART_BPS_9600;
        configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
        configuration.SPED.uartParity = MODE_00_8N1;

        configuration.OPTION.subPacketSetting = SPS_200_00;
        configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_ENABLED;
        configuration.OPTION.transmissionPower = POWER_22;

        configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
        configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
        configuration.TRANSMISSION_MODE.enableLBT = LBT_ENABLED;
        configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;

        // Set configuration changed and set to not hold the configuration
        ResponseStatus rs = e220ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE);
        Serial.println(rs.getResponseDescription());
        Serial.println(rs.code);
        c.close();

        printParameters(configuration);
    }
    else
    {
        MaintainDTC(DTC_NO_LORA_FOUND, DTC_WARN, true);
    }
    return returnval;
}

void LoRa_Process()
{
    if (e220ttl.available() > 1)
    {
        ResponseContainer rc = e220ttl.receiveMessageRSSI();
        // Is something goes wrong print error
        if (rc.status.code != 1)
        {
            Serial.println(rc.status.getResponseDescription());
        }
        else
        {
            // Print the data received
            Serial.println(rc.status.getResponseDescription());
            Serial.println(rc.data);
            Serial.print("RSSI: ");
            Serial.println(rc.rssi, DEC);
        }
    }
}

void sendStatus_LoRa()
{
    struct
    {
        MessageType_t type = "STATUS";
        MessageStatus_t status;
    } __attribute__((packed)) sendStatus;

    sendStatus.status.nodeid = 0x0002;
    sendStatus.status.millis = millis();
    sendStatus.status.faction_active = 1;
    sendStatus.status.faction_1_timer = 0xBBBBBBBB;
    sendStatus.status.faction_2_timer = 0xCCCCCCCC;
    sendStatus.status.faction_3_timer = 0xDDDDDDDD;

    ResponseStatus rs = e220ttl.sendFixedMessage(0xFF, 0xFF, 23, (byte *)&sendStatus, sizeof(sendStatus));
    Serial.println(rs.getResponseDescription());
}

void printParameters(struct Configuration configuration)
{
    Serial.println("----------------------------------------");

    Serial.print(F("HEAD : "));
    Serial.print(configuration.COMMAND, HEX);
    Serial.print(" ");
    Serial.print(configuration.STARTING_ADDRESS, HEX);
    Serial.print(" ");
    Serial.println(configuration.LENGHT, HEX);
    Serial.println(F(" "));
    Serial.print(F("AddH : "));
    Serial.println(configuration.ADDH, HEX);
    Serial.print(F("AddL : "));
    Serial.println(configuration.ADDL, HEX);
    Serial.println(F(" "));
    Serial.print(F("Chan : "));
    Serial.print(configuration.CHAN, DEC);
    Serial.print(" -> ");
    Serial.println(configuration.getChannelDescription());
    Serial.println(F(" "));
    Serial.print(F("SpeedParityBit     : "));
    Serial.print(configuration.SPED.uartParity, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.SPED.getUARTParityDescription());
    Serial.print(F("SpeedUARTDatte     : "));
    Serial.print(configuration.SPED.uartBaudRate, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.SPED.getUARTBaudRateDescription());
    Serial.print(F("SpeedAirDataRate   : "));
    Serial.print(configuration.SPED.airDataRate, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.SPED.getAirDataRateDescription());
    Serial.println(F(" "));
    Serial.print(F("OptionSubPacketSett: "));
    Serial.print(configuration.OPTION.subPacketSetting, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.OPTION.getSubPacketSetting());
    Serial.print(F("OptionTranPower    : "));
    Serial.print(configuration.OPTION.transmissionPower, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.OPTION.getTransmissionPowerDescription());
    Serial.print(F("OptionRSSIAmbientNo: "));
    Serial.print(configuration.OPTION.RSSIAmbientNoise, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.OPTION.getRSSIAmbientNoiseEnable());
    Serial.println(F(" "));
    Serial.print(F("TransModeWORPeriod : "));
    Serial.print(configuration.TRANSMISSION_MODE.WORPeriod, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
    Serial.print(F("TransModeEnableLBT : "));
    Serial.print(configuration.TRANSMISSION_MODE.enableLBT, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
    Serial.print(F("TransModeEnableRSSI: "));
    Serial.print(configuration.TRANSMISSION_MODE.enableRSSI, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
    Serial.print(F("TransModeFixedTrans: "));
    Serial.print(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);
    Serial.print(" -> ");
    Serial.println(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());

    Serial.println("----------------------------------------");
}