/**
 * @file wifiswitcher.cpp
 * @author Radim Buráň (xburan03@stud.fit.vutbr.cz)
 */

#include "wifiswitcher.hpp"

status_t currentState = NONE;
esp_netif_t* netifAP = NULL;
esp_netif_t* netifSTA = NULL;

/**
 * @brief Starts WiFi AP WebServer on 192.168.1.1
 * 
 */
void wifiAP() {
    if (netifAP == NULL) {
        netifAP = esp_netif_create_default_wifi_ap();
    }
    
    esp_netif_ip_info_t ipInfo;
    IP4_ADDR(&ipInfo.ip, 192, 168, 1, 1);
    IP4_ADDR(&ipInfo.gw, 192, 168, 1, 1);
    IP4_ADDR(&ipInfo.netmask, 255, 255, 255, 0);

    esp_netif_dhcps_stop(netifAP);
    esp_netif_set_ip_info(netifAP, &ipInfo);
    esp_netif_dhcps_start(netifAP);

    wifi_config_t ap_config = {
        .ap = {
            .ssid = WIFI_AP_SSID,
            .password = WIFI_AP_PWD,
            .ssid_len = strlen(WIFI_AP_SSID),
            .authmode = WIFI_AUTH_WPA_WPA2_PSK,
            .max_connection = 1
        },
    };

    esp_wifi_set_mode(WIFI_MODE_AP);
    esp_wifi_set_config(WIFI_IF_AP, &ap_config);
    esp_wifi_start();
    currentState = AP;
}

void wifiSTA() {
    if (netifSTA == NULL) {
        netifSTA = esp_netif_create_default_wifi_sta();
    }

    char* ssid = readString(KEY_NVS_SSID);
    char* pwd = readString(KEY_NVS_PASSWORD);

    if (ssid == NULL || pwd == NULL) {
        ESP_LOGI(LOG_TAG, "WiFi SSID or PWD not configured! Switching on WiFi AP...");
        switchToAP();
        return;
    }

    wifi_config_t wifi_config = {};

    strcpy((char *)wifi_config.sta.ssid, ssid);
    strcpy((char *)wifi_config.sta.password, pwd);

    esp_wifi_set_mode(WIFI_MODE_STA);
    esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
    esp_wifi_start();
    currentState = STA;
}

void preSwitch() {
    switch (currentState) {
        case STA:
            esp_wifi_disconnect();
            [[fallthrough]];
        case AP:
            esp_wifi_stop();
            esp_wifi_set_mode(WIFI_MODE_NULL);
            break;
        default:
            break;
    }
}

void switchToAP() {
    preSwitch();
    wifiAP();
}

void switchToSTA() {
    preSwitch();
    wifiSTA();
}

void wifiStop() {
    mqttStop();
    esp_wifi_stop();
}