#!/usr/bin/python3

import ssl
import json
import xml.etree.ElementTree as ET
import http.client
from urllib.request import urlopen, Request
from urllib.parse import urljoin
from urllib.error import HTTPError


def get_context(verify):
    ctx = None
    if not verify:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
    return ctx


def get_apikey(configfile="/root/.config/syncthing/config.xml"):
    try:
        tree = ET.parse(configfile)
        root = tree.getroot()
        apikey = root.find("./gui/apikey").text
        return apikey
    except (FileNotFoundError, ET.ParseError, AttributeError) as exc:
        raise f"Exception {exc} occured"

    return None


def get_config(url="http://localhost:8384", verify=False, apikey=""):
    try:
        apikey=get_apikey()
    except:
        return None
    fullurl = f"{url}/rest/config"
    req = Request(method="GET",
                  url=fullurl)
    req.add_header("X-API-Key", apikey)
    try:
        res = urlopen(req, context=get_context(verify))

        ret = json.loads(res.read())
    except urllib.error.URLError:
        return None
    if res.status == 200:
        return ret

    return None


def set_config_options(url="http://localhost:8384", verify=False, apikey=get_apikey(), options={}):
    fullurl = f"{url}/rest/config/options"
    req = Request(method="PUT",
                  url=fullurl,
                  data=json.dumps(options).encode())
    req.add_header("Content-Type", "application/json")
    req.add_header("X-API-Key", apikey)
    try:
        res = urlopen(req, context=get_context(verify))
    except HTTPError as err:
        if err.status != 307:
            return False
        req.full_url = urljoin(url, err.headers['Location'])
        res = urlopen(req, context=get_context(verify))
    except urllib.error.URLError:
        return None
    if res.status == 200:
        return True

    return None

def set_config_gui(url="http://localhost:8384", verify=False, apikey=get_apikey(), gui={}):
    fullurl = f"{url}/rest/config/gui"
    req = Request(method="PUT",
                  url=fullurl,
                  data=json.dumps(gui).encode())
    req.add_header("Content-Type", "application/json")
    req.add_header("X-API-Key", apikey)
    try:
        res = urlopen(req, context=get_context(verify))
    except HTTPError as err:
        if err.status != 307:
            return False
        req.full_url = urljoin(url, err.headers['Location'])
        res = urlopen(req, context=get_context(verify))
    except http.client.RemoteDisconnected as err:
        return True
    except urllib.error.URLError:
        return None
    if res.status == 200:
        return True

    return None

## deprecated
def _set_config(url="http://localhost:8384", verify=False, apikey=get_apikey(), config={}):
    fullurl = f"{url}/rest/config"
    req = Request(method="POST",
                  url=fullurl,
                  data=json.dumps(config).encode())
    req.add_header("Content-Type", "application/json")
    req.add_header("X-API-Key", apikey)
    try:
        res = urlopen(req, context=get_context(verify))
    except HTTPError as err:
        if err.status != 307:
            return None
        req.full_url = urljoin(url, err.headers['Location'])
        res = urlopen(req, context=get_context(verify))
    except urllib.error.URLError:
        return None
    if res.status == 200:
        return True

    return None


def insync(url="http://localhost:8384", verify=False, apikey=get_apikey()):
    fullurl = f"{url}/rest/config/restart-required"
    req = Request(method="GET",
                  url=fullurl)
    req.add_header("X-API-Key", apikey)
    try:
        res = urlopen(req, context=get_context(verify))
        ret = json.loads(res.read())
        if res.status == 200:
            return ret
    except urllib.error.URLError:
        return None

    return None


def restart(url="http://localhost:8384", verify=False, apikey=get_apikey()):
    fullurl = f"{url}/rest/system/restart"
    req = Request(method="POST",
                  url=fullurl)
    req.add_header("X-API-Key", apikey)
    try:
        res = urlopen(req, context=get_context(verify))
        if res.status == 200:
            return {}
    except urllib.error.URLError:
        return None

    return None