# Copyright (C) 2010 Canonical
#
# Authors:
#  Michael Vogt
#  Gary Lasker
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; version 3.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

import logging
import os

from gi.repository import WebKit2 as webkit
from gi.repository import Gtk
from gi.repository import Pango
import urlparse

from softwarecenter.i18n import get_language
from softwarecenter.paths import SOFTWARE_CENTER_CACHE_DIR
from softwarecenter.enums import WEBKIT_USER_AGENT_SUFFIX
from softwarecenter.utils import get_oem_channel_descriptor

from gi.repository import Soup


LOG = logging.getLogger(__name__)


class SCWebKit(webkit.WebView):
    def __init__(self):
        super(SCWebKit, self).__init__()
        """ this sets the defaults for webkit, its important that this gets
            run if you want a secure webkit session
        """
        context = self.get_context()

        # enable certificates validation in webkit views unless specified otherwise
        if "SOFTWARE_CENTER_FORCE_DISABLE_CERTS_CHECK" in os.environ:
            context.set_tls_errors_policy(webkit.TLSErrorsPolicy.IGNORE)
            # WARN the user!! Do not remove this
            LOG.warning("SOFTWARE_CENTER_FORCE_DISABLE_CERTS_CHECK " +
                        "has been specified, all purchase transactions " +
                        "are now INSECURE and UNENCRYPTED!!")

        # cookies by default
        fname = os.path.join(SOFTWARE_CENTER_CACHE_DIR, "cookies.txt")
        # clear cookies again in a new session, see #1018347 comment #4
        # there is no "logout" support right now on any of the USC pages
        try:
            os.remove(fname)
        except OSError:
            pass
        cookie_manager = context.get_cookie_manager()
        cookie_manager.set_persistent_storage(fname,
                                              webkit.CookiePersistentStorage.TEXT)


class SoftwareCenterWebView(SCWebKit):
    """ A customized version of the regular webview

    It will:
    - send Accept-Language headers from the users language
    - disable plugins
    - send a custom user-agent string
    - auto-fill in id_email in login.ubuntu.com
    """

    # javascript to auto fill email login on login.ubuntu.com
    AUTO_FILL_SERVER = "https://login.ubuntu.com"
    AUTO_FILL_EMAIL_JS = """
document.getElementById("id_email").value="%s";
document.getElementById("id_password").focus();
"""

    def __init__(self):
        # actual webkit init
        super(SoftwareCenterWebView, self).__init__()
        self.connect("resource-load-started",
                     self._on_resource_request_starting)
        self.connect("load-changed",
            self._on_load_status_changed)
        settings = self.get_settings()
        settings.set_property("enable-plugins", False)
        settings.set_property("user-agent", self._get_user_agent_string())
        self._auto_fill_email = ""

    def set_auto_insert_email(self, email):
        self._auto_fill_email = email

    def _get_user_agent_string(self):
        settings = self.get_settings()
        user_agent_string = settings.get_property("user-agent")
        user_agent_string += " %s " % WEBKIT_USER_AGENT_SUFFIX
        user_agent_string += get_oem_channel_descriptor()
        return user_agent_string

    def _on_resource_request_starting(self, view, res, req):
        lang = get_language()
        if lang:
            headers = req.get_http_headers()
            if headers:
                headers.append("Accept-Language", lang)

    def _maybe_auto_fill_in_username(self):
        uri = self.get_uri()
        if self._auto_fill_email and uri.startswith(self.AUTO_FILL_SERVER):
            self.run_javascript(
                self.AUTO_FILL_EMAIL_JS % self._auto_fill_email)
            # ensure that we have the keyboard focus
            self.grab_focus()

    def _on_load_status_changed(self, view, load_event):
        if load_event == webkit.LoadEvent.FINISHED:
            self._maybe_auto_fill_in_username()


class ScrolledWebkitWindow(Gtk.VBox):

    def __init__(self, include_progress_ui=False):
        super(ScrolledWebkitWindow, self).__init__()
        # get webkit
        self.webkit = SoftwareCenterWebView()
        # add progress UI if needed
        if include_progress_ui:
            self._add_progress_ui()
        # create main webkitview
        self.pack_start(self.webkit, True, True, 0)
        self.show_all()

    def _add_progress_ui(self):
        # create toolbar box
        self.header = Gtk.HBox()
        # add spinner
        self.spinner = Gtk.Spinner()
        self.header.pack_start(self.spinner, False, False, 6)
        # add a url to the toolbar
        self.url = Gtk.Label()
        self.url.set_ellipsize(Pango.EllipsizeMode.END)
        self.url.set_alignment(0.0, 0.5)
        self.url.set_text("")
        self.header.pack_start(self.url, True, True, 0)
        # frame around the box
        self.frame = Gtk.Frame()
        self.frame.set_border_width(3)
        self.frame.add(self.header)
        self.pack_start(self.frame, False, False, 6)
        # connect the webkit stuff
        self.webkit.connect("notify::uri", self._on_uri_changed)
        self.webkit.connect("load-changed",
            self._on_load_status_changed)

    def _on_uri_changed(self, view, pspec):
        prop = pspec.name
        uri = view.get_property(prop)
        # the full uri is irrelevant for the purchase view, but it is
        # interesting to know what protocol/netloc is in use so that the
        # user can verify its https on sites he is expecting
        scheme, netloc, path, params, query, frag = urlparse.urlparse(uri)
        if scheme == "file" and netloc == "":
            self.url.set_text("")
        else:
            self.url.set_text("%s://%s" % (scheme, netloc))
        # start spinner when the uri changes
        #self.spinner.start()

    def _on_load_status_changed(self, view, load_event):
        if load_event == webkit.LoadEvent.STARTED:
            self.spinner.start()
            self.spinner.show()
        if load_event == webkit.LoadEvent.FINISHED:
            self.spinner.stop()
            self.spinner.hide()
