#include "mbed.h"
#include "mtsas.h"
#include "filesystem.h"
#include "https.h"

DigitalOut led(LED1);
Ticker tick;
void tock() {
  led = !led;
}

// APN of your SIM (applicable for GSM radios)
string APN = "";

// model and serial of device
string MODEL = "";
string SERIAL = "";

int main(){
    Serial debug(USBTX, USBRX);
    debug.baud(115200);
    
    tick.attach(&tock, 0.5);
  
    // Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
    MTSLog::setLogLevel(MTSLog::TRACE_LEVEL);
    logInfo("Program start");
    
    // Dragonfly
    MTSSerialFlowControl io(RADIO_TX, RADIO_RX, RADIO_RTS, RADIO_CTS);
    // Nucleo
    //MTSSerialFlowControl io(D8, D2, D3, D6);
    io.baud(115200); 
    Cellular* radio = CellularFactory::create(&io);
    if( ! radio) {
        logFatal("Radio initialization failed");
        return 1;
    }
    Transport::setTransport(radio);
    
    for (int i = 0; i < 10; i++) {
        if (i >= 10) {
            logError("Failed to set APN to %s", APN.c_str());
        }
        if (radio->setApn(APN) == MTS_SUCCESS) {
            logInfo("Successfully set APN to %s", APN.c_str());
            break;
        } else {
            wait(1);
        }
    }
    
    // Establish PPP link
    // This can also be done on an as needed basis
    for (int i = 0; i < 10; i++) {
        if (i >= 10) {
            logError("Failed to establish PPP link");
        }
        if (radio->connect() == true) {
            logInfo("Successfully established PPP link");
            break;
        } else {
            wait(1);
        }
    }

    // Mount the filesystem
    bool fs_mounted = mount_filesystem();
    if (fs_mounted) {
        logInfo("Successfully mounted filesystem");
    } else {
        logError("Failed to mount filesystem");
    }

    char recv_buf[512];
    HTTPClient http;
    HTTPText recv(recv_buf, sizeof(recv_buf));
    string url = "https://nucleus-connect.axeda.com/ammp/data/1/" + MODEL + "!" + SERIAL;

    // Load root CA certificate(s) defined in https.h
    logInfo("Loading certificate(s)");
    if(http.addRootCACertificate(CERTIFICATES) != HTTP_OK) {
        logError("Failed to load certificate(s)");
    }
    
    /* Enable or disable certificate validation
     * VERIFY_PEER validates server certificate (using root certs added above) and fails
     * the connection if certificate validation fails
     * VERIFY_NONE skips certificate validation
     */
    http.setPeerVerification(VERIFY_PEER);

    while (true) {
        // All of the HTTP operations are the same after enabling or disabling
        // verification and loading certificates

        // Get some data....
	char data[] = "{\"data\":[{\"dataItems\":{\"mental_trauma\":70,\"physical_trauma\":10,\"emotional_trauma\":30}}]}";
	//Alternatively, can use simple HTTPText, but HTTPJson allows for easy addition of key-value pairs
	HTTPJson send(data);

        // Do some HTTP operations...
	HTTPResult res;
	res = http.post(url.c_str(), send, &recv);
	if(res == HTTP_OK) {
		logInfo("HTTPS POST Succeeded [%d][%s]", http.getHTTPResponseCode(), recv_buf);	
	} else {
		logError("HTTPS POST Failed [%d][%s]", http.getHTTPResponseCode(), httpResToStr(res));
	}

        // Write data to file in filesystem
        if (fs_mounted) {
            int ret;
            int file_handle;
            char file[] = "log.txt";
            char msg[] = "hello world!\n";

            file_handle = SPIFFS_open(fs, file, SPIFFS_CREAT | SPIFFS_APPEND | SPIFFS_RDWR, 0);
            if (file_handle < 0) {
                logError("Failed to open %s", file);
            } else {
                ret = SPIFFS_write(fs, file_handle, msg, sizeof(msg));
                if (ret < 0) {
                    logError("Failed to write to %s", file);
                } else {
                    logInfo("Wrote %d/%d bytes to %s", ret, sizeof(msg), file);
                }
                SPIFFS_close(fs, file_handle);
            }
        }

        wait(30);
    }
    
    //Disconnect PPP link
    radio->disconnect();
    
    return 0;
}

