# 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 os

from gi.repository import WebKit 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
from gi.repository import WebKit


def global_webkit_init():
    session = WebKit.get_default_session()
    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_jar = Soup.CookieJarText.new(fname, False)
    session.add_feature(cookie_jar)
global_webkit_init()


class SoftwareCenterWebView(webkit.WebView):
    """ A customized version of the regular webview

    It will:
    - send Accept-Language headers from the users language
    - disable plugings
    - 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
        webkit.WebView.__init__(self)
        self.connect("resource-request-starting",
                     self._on_resource_request_starting)
        self.connect("notify::load-status",
            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, frame, res, req, resp):
        lang = get_language()
        if lang:
            message = req.get_message()
            if message:
                headers = message.get_property("request-headers")
                headers.append("Accept-Language", lang)
        #def _show_header(name, value, data):
        #    print name, value
        #headers.foreach(_show_header, None)

    def _maybe_auto_fill_in_username(self):
        uri = self.get_uri()
        if self._auto_fill_email and uri.startswith(self.AUTO_FILL_SERVER):
            self.execute_script(
                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, pspec):
        prop = pspec.name
        status = view.get_property(prop)
        if status == webkit.LoadStatus.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.scroll = Gtk.ScrolledWindow()
        self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC,
                               Gtk.PolicyType.AUTOMATIC)
        self.pack_start(self.scroll, True, True, 0)
        # embed the webkit view in a scrolled window
        self.scroll.add(self.webkit)
        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("notify::load-status",
            self._on_load_status_changed)

    def _on_uri_changed(self, view, pspec):
        prop = pspec.name
        uri = view.get_property(prop)
        # the full uri is irellevant for the purchase view, but it is
        # interessting 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, pspec):
        prop = pspec.name
        status = view.get_property(prop)
        #print status
        if status == webkit.LoadStatus.PROVISIONAL:
            self.spinner.start()
            self.spinner.show()
        if (status == webkit.LoadStatus.FINISHED or
            status == webkit.LoadStatus.FAILED):
            self.spinner.stop()
            self.spinner.hide()
