import simpleHttpServer, json
import machine

import time
_hex_byte_cache = None


def unquote(string):
    """unquote('abc%20def') -> b'abc def'."""
    global _hex_byte_cache

    # Note: strings are encoded as UTF-8. This is only an issue if it contains
    # unescaped non-ASCII characters, which URIs should not.
    if not string:
        return b''

    if isinstance(string, str):
        string = string.replace('+', ' ')
        string = string.encode('utf-8')

    bits = string.split(b'%')
    if len(bits) == 1:
        return string

    res = [bits[0]]
    append = res.append

    # Build cache for hex to char mapping on-the-fly only for codes
    # that are actually used
    if _hex_byte_cache is None:
        _hex_byte_cache = {}

    for item in bits[1:]:
        try:
            code = item[:2]
            char = _hex_byte_cache.get(code)
            if char is None:
                char = _hex_byte_cache[code] = bytes([int(code, 16)])
            append(char)
            append(item[2:])
        except KeyError:
            append(b'%')
            append(item)

    return b''.join(res)


class ConfigHttpServer(simpleHttpServer.SimpleHttpServer):

    def __init__(self, server_socket):
        super(ConfigHttpServer, self).__init__(self.config_web_page, self.request_call_back, server_socket)

    def request_call_back(self, request, client_socket):
        if len(request) == 0:
            return

        print("request = ", request)
        url = request[0].split(' ')[1]
        if url.count('ssid='):
            params = url.split('&')
            station_id = params[0].split('=')[1]
            password = params[1].split('=')[1]
            config = {"ssid": unquote(station_id), "password": unquote(password)}
            print(json.dumps(config))
            self.write_config(config)
            self.reboot_device(client_socket, station_id)

    def reboot_device(self, client_socket, station_id):
        client_socket.send(self.rebooting_web_page(station_id))
        client_socket.close()
        time.sleep(2)
        machine.reset()

    def write_config(self, config):
        f = open("config.json", 'w')
        f.write(json.dumps(config))
        f.close()

    def rebooting_web_page(self, station_id):
        return "rebooting to connect to " + unquote(station_id)

    def config_web_page(self):
        return """
    <!DOCTYPE html>
    <html>
    <body>

    <h2>Configure Network</h2>
    <p>enter your network ssid and password</p>

    <form action="">
    ssid:<br>
    <input type="text" name="ssid">
    <br>
    password:<br>
    <input type="text" name="password">
    <br><br>
    <input type="submit">
    </form>

    </body>
    </html>
        """
