/*
 *  This sketch tries to connect to the best AP available
 *  and tests for captive portals on open networks
 *
 */

#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>

WiFiMulti wifiMulti;

// callback used to check Internet connectivity
bool testConnection(){
  HTTPClient http;
  http.begin("http://www.espressif.com");
  int httpCode = http.GET();
  // we expect to get a 301 because it will ask to use HTTPS instead of HTTP
  if (httpCode == HTTP_CODE_MOVED_PERMANENTLY) return true;
  return false;
}

void setup()
{
    Serial.begin(115200);
    delay(10);

    wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1");
    wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
    wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");

    // These options can help when you need ANY kind of wifi connection to get a config file, report errors, etc.
    wifiMulti.setStrictMode(false);  // Default is true.  Library will disconnect and forget currently connected AP if it's not in the AP list.
    wifiMulti.setAllowOpenAP(true);   // Default is false.  True adds open APs to the AP list.
    wifiMulti.setConnectionTestCallbackFunc(testConnection);   // Attempts to connect to a remote webserver in case of captive portals.

    Serial.println("Connecting Wifi...");
    if(wifiMulti.run() == WL_CONNECTED) {
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
    }
}

void loop()
{
    static bool isConnected = false; 
    uint8_t WiFiStatus = wifiMulti.run();
    
    if (WiFiStatus == WL_CONNECTED) {
        if (!isConnected) {
            Serial.println("");
            Serial.println("WiFi connected");
            Serial.println("IP address: ");
            Serial.println(WiFi.localIP());
        }
        isConnected = true;
    } else {
        Serial.println("WiFi not connected!");
        isConnected = false; 
        delay(5000);
    }
}
