try:
    import usocket as socket
except:
    import socket
    
from machine import Pin

def se_connecter():
    global adresse_serveur
    # Importation du module (bibliothèque) "network"
    import network
    import utime
    import ujson
    # Paramètres du réseau
    # Importation des réseaux connus
    try:
        with open('/networks.json','r') as netfile:
            net_connus = ujson.load(netfile)
    except:
        net_connus = {}
        
    net_list = list(net_connus.keys())
    net_list.sort()
    
    if len(net_list) > 0:
        #Il existe des réseaux répertoriés dans le fichier .json
        subnet = '255.255.255.0'
        dns = '8.8.8.8'
        
        # La classe WLAN du module "network" contient toutes les méthodes de gestion réseau
        # Création d'une instance de l'objet WIFI de type "Station" (borne)
        wlan = network.WLAN(network.STA_IF)
        # Activation de l'interface Wifi
        wlan.active(True)
        #Scrutation des réseaux aux alentours de ESP32
        reseaux_dispo = wlan.scan()
        #Importation des ssid des réseaux présents dans l'environnement ESP32
        net_name = [n[0].decode('utf-8') for n in reseaux_dispo]

        #Premièrement, essais pour se connecter à un réseau WIFI connu
        for net in net_list:
            #Scrutation des réseaux dans .json
            if net < 0:
                continue   #La clé -1 est repérée (réservée au point d'accès, on continue la boucle for
            ssid = net_connus[net]['ssid']
            if ssid in net_name:
                #Le réseau identifié dans le fichier .json est présent dans l'environnement
                print("Essai de connexion sur : ", ssid)
                ip = net_connus[net]['ip']
                gateway = net_connus[net]['gateway']
                wlan.ifconfig((ip, subnet, gateway,dns))
                wlan.connect(ssid, net_connus[net]['password'])
                utime.sleep(5)
                if wlan.isconnected():
                    print("Connexion avec succes !")
                    print('Configuration de la station WIFI :', wlan.ifconfig())
                    adresse_serveur = ip
                    break   #Connexion : sortie de la boucle for
                print("Echec de la connexion !")
        
        #Deuxièmement, essai pour se connecter au point d'accès (repéré par -1 dans .json)
        if not wlan.isconnected():
            wlan.active(False)
            for net in net_list:
                #Scrutation des réseaux dans .json
                if net>=0:
                    continue   #Les clés positives sont passées
                wlan = network.WLAN(network.AP_IF)
                wlan.active(True)
                ip = net_connus[net]['ip']
                gateway = net_connus[net]['gateway']
                wlan.ifconfig((ip, subnet, gateway,dns))
                wlan.connect(ssid, net_connus[net]['password'])
                print("Création d'un point d'accès WIFI !")
                print('Configuration du point d\'accès WIFI :', wlan.ifconfig())
            
   
def se_deconnecter():
    import network
    wlan = network.WLAN(network.STA_IF)
    wlan.disconnect()
    wlan.active(False)

def page_web():
    if led.value() == 1:
        etat_gpio2 = "OFF"
    else:
        etat_gpio2 = "ON"
        
    html = """
    <html>
        <head>
        <title>Commande LED ESP32</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta charset="utf-8"/>
        <link rel="icon" href="data:,">
        <style>
            html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
            h1{color: #0F3376; padding: 2vh;}
            p{font-size: 1.5rem;}
            .button{display: inline-block; background-color: #e7bd3b; border: none; border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
            .button2{background-color: #4286f4;}
        </style>
        </head>
        <body>
        <h1>Commande LED ESP32</h1> 
        <p>Etat LED : <strong>""" + etat_gpio2 + """</strong></p>
        <p><a href="/?led=on"><button class="button">ON</button></a></p>
        <p><a href="/?led=off"><button class="button button2">OFF</button></a></p>
        </body>
    </html>
    """
    return html

adresse_serveur = ""
se_connecter()
#Adresse de la carte microprogrammée
#ATTENTION : si plusieurs cartes cohabitent sur le même réseau, le dernier nombre doit être unique (ici j'ai choisi : 209)
print("L'adresse IP à utiliser sur le client : ", adresse_serveur)
led = Pin(22, Pin.OUT)
led.value(1)

#Création d'un connecteur (socket)
#Famille d'adresses : AF_INET (adresse internet de type IPv4)
#Type de socket : SOCK_STREAM (Protocole TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Liaison du socket d'écoute à une adresse et à un port d'écoute
#Le port 80 correspond au port HTML
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((adresse_serveur,80))
#Attente de la requête d'une client : le serveur écoute... et attend une requête
print('Serveur prêt, en attente d\'une requête !')
s.listen(5)

while True:
  #Un client se connecte, le serveur accepte la connexion. La méthode renvoie 2 informations :
  #connexion_client : un nouvel objet "socket" est créé, il permet l'échange de données avec le client
  #adresse_client : l'adresse du client est donnée (contient 2 informations : l'IP et le numéro de port)
  connexion_client, adresse_client = s.accept()
  print('Client connecté. Son adresse IP est %s, son port est %s' % (adresse_client[0], adresse_client[1]))
  #Réception des données envoyées par le client
  #1024 représente la taille maximale des données. Si la taille des données reçues est supérieure, une nouvelle méthode .recv est nécessaire
  requete = connexion_client.recv(1024)
  #En Python, les données échangées sont de type "bytes" (octets). Elles sont représentées comme des chaînes de caractères avec le préfixe "b"
  #"b" se traduit par "bonjour"
  #Conversion de "requete" (ce qui a été envoyé par le client) en une chaîne de caractères portant le même nom
  requete = str(requete)
  print('Voici se qui a été transmis par le client :\n %s' % requete)
  #Recherche des informations "/?led=on" ou "/?led=off" dans la requête envoyée par le client
  #led_on ou led_off contiennent la position du premier caractère soit /. Attention, le "b" (bonjour) n'est pas compté
  led_on = requete.find('/?led=on')
  led_off = requete.find('/?led=off')
  if led_on == 6:
    print('LED ON')
    led.value(0)
  if led_off == 6:
    print('LED OFF')
    led.value(1)
    #Contient la future page WEB actualisée avec l'état de la LED
  reponse = page_web()
  #Envoi au client de l'entête de la page HTML
  connexion_client.send('HTTP/1.1 200 OK\n')
  connexion_client.send('Content-Type: text/html\n')
  connexion_client.send('Connection: close\n\n')
  #Envoi de l'intégralité des données (méthode .sendall)
  connexion_client.sendall(reponse)
  #Fermeture du connecteur pour dialoguer avec le client
  connexion_client.close()