import json
import hashlib
import http.cookiejar
import urllib.parse
import urllib.request
from http.cookies import SimpleCookie

_headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}

class UrllibClient:
    """Simple HTTP Session Client, keeps cookies."""

    def __init__(self):
        self.cookie_jar = http.cookiejar.CookieJar()
        self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.cookie_jar))
        urllib.request.install_opener(self.opener)

    def get(self, url, headers={}):
        request = urllib.request.Request(url, headers=headers)
        return self._request(request)

    def post(self, url, data=None, headers={}):
        postdata = urllib.parse.urlencode(data).encode()
        request = urllib.request.Request(url, postdata, headers)
        return self._request(request)

    def _request(self, request):
        response = self.opener.open(request)
        response.status_code = response.getcode()
        response.data = response.read().decode('utf-8')
        return response


def json_loads(string):
    try:
        return json.loads(string)
    except:
        return None


def upload(data):
    client, cookie = UrllibClient(), SimpleCookie()

    cookie.load(vars(client.get('https://rentry.co'))['headers']['Set-Cookie'])
    csrftoken = cookie['csrftoken'].value

    json_data = json.dumps(data)
    md5sum = hashlib.md5(json_data.encode('utf-8')).hexdigest()

    payload = {
        'csrfmiddlewaretoken': csrftoken,
        'url': md5sum,
        'edit_code': '',
        'text': json_data
    }

    response = client.post('https://rentry.co/api/new', payload, headers=_headers)

    if response.status_code == 200:
        json_response = json_loads(response.data)
        return {
            "service": "rentry",
            "name": json_response["slug"],
            "key": f"https://rentry.co/{json_response['slug']}",
            "md5sum": md5sum
        }
    else:
        return None

