import http.server, socketserver, urllib.request, urllib.error, pathlib, shutil, time, json
ROOT=pathlib.Path(__file__).parent
config=ROOT/'gh-config'
config.mkdir(exist_ok=True)
shutil.copyfile(pathlib.Path.home()/'.config/gh/hosts.yml',config/'hosts.yml')
(config/'config.yml').write_text('http_unix_socket: '+str(ROOT/'github.sock')+'\n')
class Server(socketserver.ThreadingMixIn,socketserver.UnixStreamServer):
    daemon_threads=True
class Handler(http.server.BaseHTTPRequestHandler):
    def log_message(self,*args): pass
    def do_GET(self): self.handle_request()
    def do_POST(self): self.handle_request()
    def handle_request(self):
        host=self.headers.get('Host','api.github.com')
        data=self.rfile.read(int(self.headers.get('Content-Length','0'))) or None
        if '/actions/runs?' in self.path and 'status=action_required' in self.path:
            status=403
            headers={'Content-Type':'application/json','Retry-After':'60','X-RateLimit-Remaining':'0','X-RateLimit-Reset':str(int(time.time())+60)}
            body=json.dumps({'message':'API rate limit exceeded. Please retry after the rate limit resets.','documentation_url':'https://docs.github.com/rest/using-the-rest-api/rate-limits-for-the-rest-api'}).encode()
            label='REFUSED'
        else:
            req=urllib.request.Request('https://'+host+self.path,data=data,method=self.command,headers={k:v for k,v in self.headers.items() if k.lower() not in ['host','connection','content-length','accept-encoding']})
            try:
                response=urllib.request.urlopen(req,timeout=60)
            except urllib.error.HTTPError as e: response=e
            status=response.code; headers=dict(response.headers); body=response.read(); label='PASSED'
            if status >= 400:
                (ROOT/'upstream-error.txt').write_bytes(body)
                if data: (ROOT/'upstream-query.json').write_bytes(data)
        with (ROOT/'proxy.log').open('a') as log: log.write(f'{label} {status} {self.command} {host}{self.path}\n')
        self.send_response(status)
        for k,v in headers.items():
            if k.lower() not in ['transfer-encoding','connection','content-length','content-encoding']: self.send_header(k,v)
        self.send_header('Content-Length',str(len(body))); self.end_headers(); self.wfile.write(body)
Server(str(ROOT/'github.sock'),Handler).serve_forever()
