# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.


"""
add permissions to the profile
"""

__all__ = ['MissingPrimaryLocationError', 'MultiplePrimaryLocationsError',
           'DuplicateLocationError', 'BadPortLocationError',
           'LocationsSyntaxError', 'Location', 'ServerLocations',
           'Permissions']

import codecs
import itertools
import os
try:
    import sqlite3
except ImportError:
    from pysqlite2 import dbapi2 as sqlite3
import urlparse

# http://hg.mozilla.org/mozilla-central/file/b871dfb2186f/build/automation.py.in#l28
_DEFAULT_PORTS = { 'http': '8888',
                   'https': '4443',
                   'ws': '4443',
                   'wss': '4443' }

class LocationError(Exception):
    """Signifies an improperly formed location."""

    def __str__(self):
        s = "Bad location"
        if self.message:
            s += ": %s" % self.message
        return s


class MissingPrimaryLocationError(LocationError):
    """No primary location defined in locations file."""

    def __init__(self):
        LocationError.__init__(self, "missing primary location")


class MultiplePrimaryLocationsError(LocationError):
    """More than one primary location defined."""

    def __init__(self):
        LocationError.__init__(self, "multiple primary locations")


class DuplicateLocationError(LocationError):
    """Same location defined twice."""

    def __init__(self, url):
        LocationError.__init__(self, "duplicate location: %s" % url)


class BadPortLocationError(LocationError):
    """Location has invalid port value."""

    def __init__(self, given_port):
        LocationError.__init__(self, "bad value for port: %s" % given_port)


class LocationsSyntaxError(Exception):
    """Signifies a syntax error on a particular line in server-locations.txt."""

    def __init__(self, lineno, err=None):
        self.err = err
        self.lineno = lineno

    def __str__(self):
        s = "Syntax error on line %s" % self.lineno
        if self.err:
            s += ": %s." % self.err
        else:
            s += "."
        return s


class Location(object):
    """Represents a location line in server-locations.txt."""

    attrs = ('scheme', 'host', 'port')

    def __init__(self, scheme, host, port, options):
        for attr in self.attrs:
            setattr(self, attr, locals()[attr])
        self.options = options
        try:
            int(self.port)
        except ValueError:
            raise BadPortLocationError(self.port)

    def isEqual(self, location):
        """compare scheme://host:port, but ignore options"""
        return len([i for i in self.attrs if getattr(self, i) == getattr(location, i)]) == len(self.attrs)

    __eq__ = isEqual

    def url(self):
        return '%s://%s:%s' % (self.scheme, self.host, self.port)

    def __str__(self):
        return  '%s  %s' % (self.url(), ','.join(self.options))


class ServerLocations(object):
    """Iterable collection of locations.
    Use provided functions to add new locations, rather that manipulating
    _locations directly, in order to check for errors and to ensure the
    callback is called, if given.
    """

    def __init__(self, filename=None, add_callback=None):
        self.add_callback = add_callback
        self._locations = []
        self.hasPrimary = False
        if filename:
            self.read(filename)

    def __iter__(self):
        return self._locations.__iter__()

    def __len__(self):
        return len(self._locations)

    def add(self, location, suppress_callback=False):
        if "primary" in location.options:
            if self.hasPrimary:
                raise MultiplePrimaryLocationsError()
            self.hasPrimary = True

        self._locations.append(location)
        if self.add_callback and not suppress_callback:
            self.add_callback([location])

    def add_host(self, host, port='80', scheme='http', options='privileged'):
        if isinstance(options, basestring):
            options = options.split(',')
        self.add(Location(scheme, host, port, options))

    def read(self, filename, check_for_primary=True):
        """
        Reads the file and adds all valid locations to the ``self._locations`` array.

        :param filename: in the format of server-locations.txt_
        :param check_for_primary: if True, a ``MissingPrimaryLocationError`` exception is raised if no primary is found

        .. _server-locations.txt: http://mxr.mozilla.org/mozilla-central/source/build/pgo/server-locations.txt

        The only exception is that the port, if not defined, defaults to 80 or 443.

        FIXME: Shouldn't this default to the protocol-appropriate port?  Is
        there any reason to have defaults at all?
        """

        locationFile = codecs.open(filename, "r", "UTF-8")
        lineno = 0
        new_locations = []

        for line in locationFile:
            line = line.strip()
            lineno += 1

            # check for comments and blank lines
            if line.startswith("#") or not line:
                continue

            # split the server from the options
            try:
                server, options = line.rsplit(None, 1)
                options = options.split(',')
            except ValueError:
                server = line
                options = []

            # parse the server url
            if '://' not in server:
                server = 'http://' + server
            scheme, netloc, path, query, fragment = urlparse.urlsplit(server)
            # get the host and port
            try:
                host, port = netloc.rsplit(':', 1)
            except ValueError:
                host = netloc
                port = _DEFAULT_PORTS.get(scheme, '80')

            try:
                location = Location(scheme, host, port, options)
                self.add(location, suppress_callback=True)
            except LocationError, e:
                raise LocationsSyntaxError(lineno, e)

            new_locations.append(location)

        # ensure that a primary is found
        if check_for_primary and not self.hasPrimary:
            raise LocationsSyntaxError(lineno + 1,
                                       MissingPrimaryLocationError())

        if self.add_callback:
            self.add_callback(new_locations)


class Permissions(object):
    """Allows handling of permissions for ``mozprofile``"""

    def __init__(self, profileDir, locations=None):
        self._profileDir = profileDir
        self._locations = ServerLocations(add_callback=self.write_db)
        if locations:
            if isinstance(locations, ServerLocations):
                self._locations = locations
                self._locations.add_callback = self.write_db
                self.write_db(self._locations._locations)
            elif isinstance(locations, list):
                for l in locations:
                    self._locations.add_host(**l)
            elif isinstance(locations, dict):
                self._locations.add_host(**locations)
            elif os.path.exists(locations):
                self._locations.read(locations)

    def write_db(self, locations):
        """write permissions to the sqlite database"""

        # Open database and create table
        permDB = sqlite3.connect(os.path.join(self._profileDir, "permissions.sqlite"))
        cursor = permDB.cursor();

        # SQL copied from
        # http://mxr.mozilla.org/mozilla-central/source/extensions/cookie/nsPermissionManager.cpp
        cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts (
           id INTEGER PRIMARY KEY,
           host TEXT,
           type TEXT,
           permission INTEGER,
           expireType INTEGER,
           expireTime INTEGER)""")

        for location in locations:
            # set the permissions
            permissions = { 'allowXULXBL': 'noxul' not in location.options }
            for perm, allow in permissions.iteritems():
                if allow:
                    permission_type = 1
                else:
                    permission_type = 2

                rows = cursor.execute("PRAGMA table_info(moz_hosts)")
                count = len(rows.fetchall())

                # if the db contains 8 columns, we're using user_version 3
                if count == 8:
                    statement = "INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0, 0, 0)"
                    cursor.execute("PRAGMA user_version=3;")
                else:
                    statement = "INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0)"
                    cursor.execute("PRAGMA user_version=2;")

                cursor.execute(statement,
                               (location.host, perm, permission_type))

        # Commit and close
        permDB.commit()
        cursor.close()

    def network_prefs(self, proxy=None):
        """
        take known locations and generate preferences to handle permissions and proxy
        returns a tuple of prefs, user_prefs
        """

        # Grant God-power to all the privileged servers on which tests run.
        prefs = []
        privileged = [i for i in self._locations if "privileged" in i.options]
        for (i, l) in itertools.izip(itertools.count(1), privileged):
            prefs.append(("capability.principal.codebase.p%s.granted" % i, "UniversalXPConnect"))

            prefs.append(("capability.principal.codebase.p%s.id" % i, "%s://%s:%s" %
                        (l.scheme, l.host, l.port)))
            prefs.append(("capability.principal.codebase.p%s.subjectName" % i, ""))

        if proxy:
            user_prefs = self.pac_prefs(proxy)
        else:
            user_prefs = []

        return prefs, user_prefs

    def pac_prefs(self, user_proxy=None):
        """
        return preferences for Proxy Auto Config. originally taken from
        http://mxr.mozilla.org/mozilla-central/source/build/automation.py.in
        """
        proxy = _DEFAULT_PORTS

        # We need to proxy every server but the primary one.
        origins = ["'%s'" % l.url()
                   for l in self._locations]
        origins = ", ".join(origins)
        proxy["origins"] = origins

        for l in self._locations:
            if "primary" in l.options:
                proxy["remote"] = l.host
                proxy[l.scheme] = l.port

        # overwrite defaults with user specified proxy
        if isinstance(user_proxy, dict):
            proxy.update(user_proxy)

        # TODO: this should live in a template!
        # TODO: So changing the 5th line of the regex below from (\\\\\\\\d+)
        # to (\\\\d+) makes this code work. Not sure why there would be this
        # difference between automation.py.in and this file.
        pacURL = """data:text/plain,
function FindProxyForURL(url, host)
{
  var origins = [%(origins)s];
  var regex = new RegExp('^([a-z][-a-z0-9+.]*)' +
                         '://' +
                         '(?:[^/@]*@)?' +
                         '(.*?)' +
                         '(?::(\\\\d+))?/');
  var matches = regex.exec(url);
  if (!matches)
    return 'DIRECT';
  var isHttp = matches[1] == 'http';
  var isHttps = matches[1] == 'https';
  var isWebSocket = matches[1] == 'ws';
  var isWebSocketSSL = matches[1] == 'wss';
  if (!matches[3])
  {
    if (isHttp | isWebSocket) matches[3] = '80';
    if (isHttps | isWebSocketSSL) matches[3] = '443';
  }
  if (isWebSocket)
    matches[1] = 'http';
  if (isWebSocketSSL)
    matches[1] = 'https';

  var origin = matches[1] + '://' + matches[2] + ':' + matches[3];
  if (origins.indexOf(origin) < 0)
    return 'DIRECT';
  if (isHttp) return 'PROXY %(remote)s:%(http)s';
  if (isHttps) return 'PROXY %(remote)s:%(https)s';
  if (isWebSocket) return 'PROXY %(remote)s:%(ws)s';
  if (isWebSocketSSL) return 'PROXY %(remote)s:%(wss)s';
  return 'DIRECT';
}""" % proxy
        pacURL = "".join(pacURL.splitlines())

        prefs = []
        prefs.append(("network.proxy.type", 2))
        prefs.append(("network.proxy.autoconfig_url", pacURL))

        return prefs

    def clean_db(self):
        """Removed permissions added by mozprofile."""

        sqlite_file = os.path.join(self._profileDir, "permissions.sqlite")
        if not os.path.exists(sqlite_file):
            return

        # Open database and create table
        permDB = sqlite3.connect(sqlite_file)
        cursor = permDB.cursor();

        # TODO: only delete values that we add, this would require sending in the full permissions object
        cursor.execute("DROP TABLE IF EXISTS moz_hosts");

        # Commit and close
        permDB.commit()
        cursor.close()
