#!/usr/bin/python
from functools import cached_property
from http.cookies import SimpleCookie
from http.server import BaseHTTPRequestHandler
from socketserver import BaseServer
from time import sleep
from urllib.parse import parse_qsl, urlparse
from datatypes import htmldoc, httpReturn

class headers:
  def __init__(self, headers):
    self.headers = headers
  def items(self):
    return self.headers

class WebRequestHandler(BaseHTTPRequestHandler):
    def __init__(self, request, client_address, server: BaseServer, data=None) -> None:
      self.data = data
      super().__init__(request, client_address, server)
      
    @cached_property
    def url(self):
      return urlparse(self.path)

    @cached_property
    def query_data(self):
      return dict(parse_qsl(self.url.query))

    @cached_property
    def post_data(self):
      content_length = int(self.headers.get("Content-Length", 0))
      return self.rfile.read(content_length)

    @cached_property
    def form_data(self):
      return dict(parse_qsl(self.post_data.decode("utf-8")))

    @cached_property
    def cookies(self):
      return SimpleCookie(self.headers.get("Cookie"))

    def do_GET(self):
      if (data := self.data.respond(self)) is None:
        data = httpReturn("500 Server processing error", [("Content-type", "text/html")], 500)
      self.close_connection = data.close
      if isinstance(data.response, str):
        response = data.response.encode("utf-8", "replace")
      elif hasattr(data.response, "render"):
        try:
          response = data.response.render().encode("utf-8", "replace")
        except:
          data = httpReturn("500 Server processing error", [("Content-type", "text/html")], 500)
          response = data.response
      else:
        response = data.response
      self.send_response(data.status)
      for header in data.headers:
        self.send_header(header[0], header[1])
      self.end_headers()
      self.wfile.write(response)

    def do_POST(self):
      self.do_GET()
      
    
