import badge
import ugfx
import network
import wifi
import time
import math
import dialogs
import usocket as socket
import _thread as thread
import uos as os


badge.init()
ugfx.init()
wifi.init()

ugfx.set_lut(ugfx.LUT_FULL)

ugfx.clear(ugfx.WHITE)
ugfx.flush()
ugfx.clear(ugfx.BLACK)
ugfx.flush()
ugfx.clear(ugfx.WHITE)
ugfx.flush()

lines = []
def render_term():
  ugfx.clear(ugfx.WHITE)
  ugfx.flush()
  cy = 0
  h = ugfx.height()
  count = math.floor(h / 13)
  for line in lines[-count:]:
    ugfx.string(0, cy, line, "pixelade13", ugfx.BLACK)
    cy = cy + 13
    if cy > h:
      break
  ugfx.flush()


def print_ln(text):
  lines.append(text)
  render_term()



def send_message(pressed):
  msgb = bytes(dialogs.prompt_text("Your message:") + "\n")
  s.send(msgb)


def wifi_up():
  while not wifi.sta_if.isconnected():
    time.sleep(0.1)
    pass
  return wifi.sta_if.ifconfig()[0]


def socket_listen(port):
  s = socket.socket()
  ai = socket.getaddrinfo("0.0.0.0", port)
  addr = ai[0][-1]
  # s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  s.bind(addr)
  s.listen(5)
  return s


def webserver(s, handler):
  run = True
  while run:
    res = s.accept()
    client_s = res[0]
    client_ip = str(res[1][0])
    req = str(client_s.readline().decode("ascii")).split(" ")
    method = str(req[0]).upper()
    url = str(req[1])
    headers = []
    while True:
      cline = str(client_s.readline().decode("ascii"))
      if cline == "" or cline == "\r\n":
        break
      headers.append(cline)
    body = ""
    if method.upper == "POST":
      body = client_s.recv(8192)
    resp = bytes(handler(client_s, method, url, body, headers, client_ip).encode("utf-8"))
    client_s.send(resp)
    client_s.close()



def files_handler(url, query_parms, headers, ip):
  ret = "<h1>Files</h1>\n<p>"
  for file in os.ilistdir():
    ret += str(file) + "\n"
  ret += "</p>"
  return ret

routes = [
  ("/",          "static", "/lib/badgeweb/index.html.py"),
  ("/files",     "get",    files_handler),
#  ("/files",     "post",    files_post_handler),
#  ("/leds",      "post",   leds_handler),
#  ("/vibration", "post",   vibration_handler),
#  ("/inputs",    "post",   inputs_handler),
#  ("/screen",    "post",   screen_handler)
]

default_reply = """\
HTTP/1.0 200 OK
Server: SHA2017 Badge
Content-Type: text/html

"""

error_reply = """\
HTTP/1.0 404 Not Found/Supported
Server: SHA2017 Badge
Content-Type: text/html

<h1>Error</h1>
<h2>Possibly 404.</h2>
<p>This badge can't satisfy your combination of URL and request method.</p>
"""


def router_handler(s, method, url, body, headers, client_ip):
  print_ln(method + " request from " + client_ip + " to " + url)
  found = False
  reply = default_reply
  query_parms = {}
  if url.find("?") != -1:
    _url = url.split("?")
    url = _url[0]
    if url.find("&") != -1:
      _query_parms = _url[1].split("&")
      for parm in _query_parms:
        _parm = parm.split("=")
        query_parms[_parm[0]] = _parm[1]
  for entry in routes:
    if url == entry[0]:
      if method == "GET":
        if entry[1] == "get":
          found = True
          reply += entry[2](url, query_parms, headers, client_ip)
        elif entry[1] == "static":
          found = True
          f = open(entry[2], "r")
          reply += f.read()
          f.close()
      elif method == "POST" and entry[1] == "post":
        found = True
        reply += entry[2](url, query_parms, headers, client_ip, body)
  if found:
    return reply
  else:
    return error_reply

print_ln("Waiting for wifi...")
cur_ip = wifi_up()
print_ln("Your IP: " + cur_ip)

print_ln("Creating listening socket on port 8080...")
s = socket_listen(8080)
print_ln("Starting webserver...")
webserver(s, router_handler)

