/*
 * IdeasX UART Interface
 * Author: Tyler Berezowsky
 * Date: 20170518
 */

#include "interface/uart_interface.h"

static const char* TAG = "uart_interface.c";

static void show_WiFi_current(void)
{
    struct station_config stationConfig;
    wifi_station_get_config(&stationConfig);
    os_printf("SSID: %s\nBSSID: "MACSTR"\n", stationConfig.ssid, MAC2STR(stationConfig.bssid)); // fix MAX2STR error
}

static void show_WiFi(void)
{
    struct station_config stationConfig[5];
    uint8_t num = wifi_station_get_ap_info(stationConfig);

    os_printf("\n--------Stored Access Points---------\n");
    uint32_t i;
    for (i=0;i<num;i++)
    {
        os_printf("AP: %d/%d\n", i, (num-1));
        os_printf("\tSSID: %s\n", stationConfig[i].ssid);
        os_printf("\tPASSWORD: %s\n", stationConfig[i].password);
        if (stationConfig[i].bssid_set)
            os_printf("\tBSSID: "MACSTR"\n", MAC2STR(stationConfig[i].bssid));     // fix MAC2STR
    }
}

static void show_IP(void)
{
 	struct ip_info ipconfig;
 	wifi_get_ip_info(STATION_IF, &ipconfig);
 	if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != 0) {
 		os_printf("IP: %d.%d.%d.%d, MASK: %d.%d.%d.%d, GW: %d.%d.%d.%d\n",
 			IP2STR(&ipconfig.ip), IP2STR(&ipconfig.netmask), IP2STR(&ipconfig.gw));
 	} else {
 		os_printf("Network Status: %d\n", wifi_station_get_connect_status());
 	}
}

static void select_ap(uint8_t* str)
{
    uint8_t* token;
    uint8_t num;
    token = strtok(str, "=");
    token = strtok(NULL, ",");
    num = atoi(token);
    ESP_LOGD(TAG,"Setting to Station: %d\n", num);
    if (wifi_station_ap_change(num))
        os_printf("OK\n");
    else
        os_printf("FAIL\n");
}

static void add_ap(uint8_t* str)
{
    //strip command and seperate into SSID / password
    uint8_t* token;
    struct station_config stationConfig;
    token = strtok(str, "=");  // disregard first field
    token = strtok(NULL, ",");
    if (token != NULL) // set ssid
    {
        ESP_LOGD(TAG, "\rSSID: %s\n", token);
        os_sprintf(stationConfig.ssid, "%s", token);
    }
    token = strtok(NULL, ",");
    if (token != NULL)  // set password field
    {
        ESP_LOGD(TAG, "Password: %s\n", token);
        os_sprintf(stationConfig.password, "%s", token);

    }
    stationConfig.bssid_set = 0;
    if (wifi_station_set_config(&stationConfig))
        os_printf("OK\n");
    else
        os_printf("FAIL\n");
}

static void show_info(void)
{
    os_printf("\n--------System Information--------\n");
    os_printf("SDK: v%s\n", system_get_sdk_version());
    os_printf("Firmware Build Date:" BUILD_TIME"\n");
    os_printf("Free Heap: %d\n", system_get_free_heap_size());
    os_printf("CPU Frequency: %d MHz\n", system_get_cpu_freq());
    os_printf("System Chip ID: 0x%x\n", system_get_chip_id());
    os_printf("SPI Flash ID: 0x%x\n", spi_flash_get_id());
    os_printf("SPI Flash Size: %d\n", (1 << ((spi_flash_get_id() >> 16) & 0xff)));
    os_printf("--------Network Status------------\n");
    show_IP();
    show_WiFi_current();
    // print broker information
}

void process_command(uint8_t *str)
{
    if (!strcmp(str, "AT+RST"))         // reset
    {
        ESP_LOGI(TAG, "Manual Restarting...\n");
		system_restart();
	}
    else if (!strcmp(str, "AT+SD"))     // shutdown
    {
        ESP_LOGI(TAG, "Manual Shutdown...\n");
    }
    else if (!strcmp(str, "AT+INFO"))   // print system information
    {
        show_info();
    }
    else if (!strcmp(str, "AT+WL"))     // list all stored APs
    {
        show_WiFi();
    }
    else if (!strncmp(str, "AT+WA", 5)) // add ap
    {
        add_ap(str);
    }
    else if (!strncmp(str, "AT+WS", 5)) // manually select ap
    {
        select_ap(str);
    }
    else if (!strcmp(str, "AT+WD"))     // delete stored AP
    {
        ESP_LOGI(TAG, "N/A\n");
    }

    else if (!strcmp(str, "AT+OTA"))    // manually force OTA update
    {
        ESP_LOGI(TAG, "N/A\n");

    }
    else if (!strcmp(str, "AT+BS"))     // store MQTT broker
    {
        ESP_LOGI(TAG, "N/A\n");
    }
}