import usocket, gc
import select
global uP


try:
    l = [1, 2, 3, 4]
    del l[0:4:2]
    uP = False
except:
    uP = True

def http_post(server,port=80,path="/",postdata="",extraheader=None,content_type=None,max_redirects = 3,ignore_response=False,timeout=3,debug=False):
    global uP
    redirect = True
    n_redirects = 0
    
    if extraheader is None:
        extraheader = ""
    if content_type is None:
        content_type = "application/x-www-form-urlencoded"
    while (n_redirects < max_redirects) and redirect:
        request = ''.join(["POST ",path," HTTP/1.1\r\n",\
                  "Host: ",server,"\r\n",\
                  "User-Agent: u_http\r\n",\
                  "Accept: */*\r\n",\
                  extraheader,\
                  "Content-type: ",content_type,"\r\n",\
                  "Content-length: %i\r\n" % len(postdata),\
                  "Connection: close\r\n\r\n",\
                  postdata,\
                  "\r\n"])
        addrinfo = usocket.getaddrinfo(server, int(port))
        addr = addrinfo[0][-1]
        s = usocket.socket()
        s.setsockopt(usocket.SOL_SOCKET, usocket.SO_REUSEADDR, 1)
#        s.settimeout(5.0)
        s.connect(addr)
        if debug:
            print("Sending")
        s.send(bytes(request,'utf-8'))
        gc.collect()
        if ignore_response:
            s.close()
            return

        lno = 0
        header = True
        redirect = False
        addr = None
        body = b''
        indata = b''
        content_length = None
        poll = select.poll()
        poll.register(s, select.POLLIN|select.POLLERR|select.POLLHUP)
        while header:
            gc.collect()
            try:
                p_res = poll.poll(int(timeout*1000))
                if len(p_res) == 0:
                    if debug:
                        print("Timeout")
                    s.close()
                    break
                else:
                    p_res = p_res[0]
                    if p_res[1] & select.POLLIN:
                        if debug:
                            print("POLLIN")
                        indata = b''.join([indata,s.recv(536)])
                    if p_res[1] & select.POLLERR:
                        raise
                    if p_res[1] & select.POLLHUP:
                        if debug:
                            print("POLLHUP")
                        s.close()
                        break
            except Exception as e:
                if debug:
                    print("==EX {}".format(e))
                s.close()
                break
                
            if len(indata) == 0:
                print("==0")
                s.close()
                break
                 
            # Von null bis mehrere Headerzeilen sind nun in indata
            while (b"\r\n" in indata) and header:
                l,indata = indata.split(b"\r\n",1)
                
                l = l.decode('utf-8')
                if lno == 0:
                    proto,status,_ = l.lower().split(' ',2)
                    if not proto.startswith("http/1.1"):
                        print("!2")
                        return None
                    if status.startswith("3"):
                        redirect = True
                elif redirect and l.lower().startswith('location: '):
                    addr = l[10:]
                    if addr.lower().startswith('http://'):
                        server,path = addr[7:].split("/",1)
                        if ":" in server:
                            server,port = server.split(":",1)
                        break
                    if addr.lower().startswith('https://'):
                        raise NotImplementedError
                    if not addr.startswith('/'):
                        path = ''.join(['/',addr])
                        break
                    else:
                        path = addr
                        n_redirects = n_redirects + 1
                        print("Redirect to {} {} {}".format(server,port,path))
                        body = b''
                        break
                elif l.lower().startswith("content-length: "):
                    cl = l[16:].strip()
                    if debug:
                        print(cl)
                    try:
                        content_length = int(cl)
                    except:
                        content_length = None
                    
                elif len(l.strip()) < 2:
                    header = False
                    body = indata
                    
                lno = lno + 1
                
        while True:
            gc.collect()
            try:
                p_res = poll.poll(int(timeout*1000))
                if len(p_res) == 0:
                    if debug:
                        print("Timeout")
                    s.close()
                    break
                else:
                    p_res = p_res[0]
                    if p_res[1] & select.POLLIN:
                        if content_length is None:
                            rxlen = 536
                        else:
                            rxlen = content_length - len(body)
                            if rxlen > 536:
                                rxlen = 536
                        rx = s.recv(rxlen)
                        if debug:
                            print("BODY POLLIN {}".format(len(rx)))
                        if len(rx) == 0:
                            s.close()
                            break
                        body = b''.join([body,rx])
                    if p_res[1] & select.POLLERR:
                        if debug:
                            print("BODY POLLERR")
                        raise
                    if p_res[1] & select.POLLHUP:
                        if debug:
                            print("BODY POLLHUP")
                        s.close()
                        break
            except Exception as e:
                if debug:
                    print("==EX {}".format(e))
                s.close()
                break
            
        s.close()

    if redirect:
        return None
    if debug:
        print([len(body),content_length])
        print(body)
    return body.decode('utf-8')