#!/usr/bin/python3

import logging
import urllib.parse
import webbrowser
from urllib.parse import parse_qsl, urlencode

import gi

gi.require_version('Gtk', '3.0')
try:
    gi.require_version('WebKit2', '4.1')
except ValueError:
    # TODO: Remove once we drop support for Ubuntu 20.04 Focal
    gi.require_version('WebKit2', '4.0')

from gi.repository import Gtk, WebKit2

from keyman_config import _
from keyman_config.accelerators import init_accel
from keyman_config.dconf_util import get_option, set_option


class OptionsView(Gtk.Window):

    def __init__(self, info):
        self.accelerators = None
        self.optionurl = info["optionurl"]
        self.packageID = info["packageID"]
        self.keyboardID = info["keyboardID"]
        kbtitle = _("{packageId} Settings").format(packageId=self.packageID)
        Gtk.Window.__init__(self, title=kbtitle)
        init_accel(self)

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)

        # Keyman Desktop gets current option settings from the registry.
        # Similarly, we'll read Keyman options from DConf and update optionurl
        info = {"packageID": self.packageID, "keyboardID": self.keyboardID}
        self.options = get_option(info)
        params = ""

        if self.options:
            # Convert dictionary to query
            params = "?" + urlencode(self.options)

        s = Gtk.ScrolledWindow()
        self.webview = WebKit2.WebView()
        self.webview.connect("decide-policy", self.doc_policy)
        self.webview.load_uri(self.optionurl + params)
        s.add(self.webview)
        vbox.pack_start(s, True, True, 0)

        hbox = Gtk.Box(spacing=12)
        vbox.pack_start(hbox, False, False, 6)

        self.add(vbox)

    def doc_policy(self, web_view, decision, decision_type):
        logging.info("Checking policy")
        logging.debug("received policy decision request of type: {0}".format(decision_type.value_name))
        if decision_type == WebKit2.PolicyDecisionType.NAVIGATION_ACTION or \
                decision_type == WebKit2.PolicyDecisionType.NEW_WINDOW_ACTION:
            nav_action = decision.get_navigation_action()
            request = nav_action.get_request()
            uri = request.get_uri()
            logging.debug("nav request is for uri %s", uri)
            parsed = urllib.parse.urlparse(uri)
            if parsed.scheme == "keyman":
                logging.debug("using keyman scheme")
                if parsed.path == "cancel":
                    pass
                elif parsed.path == "ok":
                    logging.debug("submit options form")
                    # Parse the response for the option_key value and merge the updates
                    if parsed.query:
                        updated_options = parse_qsl(parsed.query, keep_blank_values=True)
                        self.options.update(updated_options)
                        self.process_option()

                self.close()
                return True

            if "options.htm" not in uri:
                logging.debug("opening uri %s in webbrowser")
                webbrowser.open(uri)
                decision.ignore()
                return True
        return False

    def process_option(self):
        # Write the Keyman options to DConf
        info = {"packageID": self.packageID, "keyboardID": self.keyboardID}
        set_option(info, self.options)
