"""Interfaces for launching and remotely controlling Web browsers."""

import os
import sys

__all__ = ["Error", "open", "get", "register"]

class Error(Exception):
    pass

_browsers = {}          # Dictionary of available browser controllers
_tryorder = []          # Preference order of available browsers

def register(name, klass, instance=None):
    """Register a browser connector and, optionally, connection."""
    _browsers[name.lower()] = [klass, instance]

def get(using=None):
    """Return a browser launcher instance appropriate for the environment."""
    if using:
        alternatives = [using]
    else:
        alternatives = _tryorder
    for browser in alternatives:
        if browser.find('%s') > -1:
            # User gave us a command line, don't mess with it.
            return GenericBrowser(browser)
        else:
            # User gave us a browser name.
            try:
                command = _browsers[browser.lower()]
            except KeyError:
                command = _synthesize(browser)
            if command[1] is None:
                return command[0]()
            else:
                return command[1]
    raise Error("could not locate runnable browser")

# Please note: the following definition hides a builtin function.

def open(url, new=0, autoraise=1):
    get().open(url, new, autoraise)

def open_new(url):      # Marked deprecated.  May be removed in 2.1.
    get().open(url, 1)


def _synthesize(browser):
    """Attempt to synthesize a controller base on existing controllers.

    This is useful to create a controller when a user specifies a path to
    an entry in the BROWSER environment variable -- we can copy a general
    controller to operate using a specific installation of the desired
    browser in this way.

    If we can't create a controller in this way, or if there is no
    executable for the requested browser, return [None, None].

    """
    if not os.path.exists(browser):
        return [None, None]
    name = os.path.basename(browser)
    try:
        command = _browsers[name.lower()]
    except KeyError:
        return [None, None]
    # now attempt to clone to fit the new name:
    controller = command[1]
    if controller and name.lower() == controller.basename:
        import copy
        controller = copy.copy(controller)
        controller.name = browser
        controller.basename = os.path.basename(browser)
        register(browser, None, controller)
        return [None, controller]
    ret

#
# Everything after this point initializes _browsers and _tryorder,
# then disappears.  Some class definitions and instances remain
# live through these globals, but only the minimum set needed to
# support the user's platform.
#

#
# Platform support for Unix
#

# This is the right test because all these Unix browsers require either
# a console terminal of an X display to run.  Note that we cannot split
# the TERM and DISPLAY cases, because we might be running Python from inside
# an xterm.
if os.environ.get("TERM") or os.environ.get("DISPLAY"):
    PROCESS_CREATION_DELAY = 4
    _tryorder = ("mozilla","netscape","kfm","grail","links","lynx","w3m")

    def _iscommand(cmd):
        """Return true if cmd can be found on the executable search path."""
        path = os.environ.get("PATH")
        if not path:
            return 0
        for d in path.split(os.pathsep):
            exe = os.path.join(d, cmd)
            if os.path.isfile(exe):
                return 1
        return 0

    class GenericBrowser:
        def __init__(self, cmd):
            self.name, self.args = cmd.split(None, 1)
            self.basename = os.path.basename(self.name)

        def open(self, url, new=0, autoraise=1):
            command = "%s %s" % (self.name, self.args)
            os.system(command % url)

        def open_new(self, url):        # Deprecated.  May be removed in 2.1.
            self.open(url)

    # Easy cases first -- register console browsers if we have them.
    if os.environ.get("TERM"):
        # The Links browser <http://artax.karlin.mff.cuni.cz/~mikulas/links/>
        if _iscommand("links"):
            register("links", None, GenericBrowser("links %s"))
        # The Lynx browser <http://lynx.browser.org/>
        if _iscommand("lynx"):
            register("lynx", None, GenericBrowser("lynx %s"))
        # The w3m browser <http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/eng/>
        if _iscommand("w3m"):
            register("w3m", None, GenericBrowser("w3m %s"))

    # X browsers have more in the way of options
    if os.environ.get("DISPLAY"):
        # First, the Netscape series
        if _iscommand("netscape") or _iscommand("mozilla"):
            class Netscape:
                "Launcher class for Netscape browsers."
                def __init__(self, name):
                    self.name = name
                    self.basename = os.path.basename(name)

                def _remote(self, action, autoraise):
                    raise_opt = ("-noraise", "-raise")[autoraise]
                    cmd = "%s %s -remote '%s' >/dev/null 2>&1" % (self.name,
                                                                  raise_opt,
                                                                  action)
                    rc = os.system(cmd)
                    if rc:
                        import time
                        os.system("%s &" % self.name)
                        time.sleep(PROCESS_CREATION_DELAY)
                        rc = os.system(cmd)
                    return not rc

                def open(self, url, new=0, autoraise=1):
                    if new:
                        self._remote("openURL(%s, new-window)"%url, autoraise)
                    else:
                        self._remote("openURL(%s)" % url, autoraise)

                # Deprecated.  May be removed in 2.1.
                def open_new(self, url):
                    self.open(url, 1)

            if _iscommand("mozilla"):
                register("mozilla", None, Netscape("mozilla"))
            if _iscommand("netscape"):
                register("netscape", None, Netscape("netscape"))

        # Next, Mosaic -- old but still in use.
        if _iscommand("mosaic"):
            register("mosaic", None, GenericBrowser("mosaic %s >/dev/null &"))

        # Konqueror/kfm, the KDE browser.
        if _iscommand("kfm") or _iscommand("konqueror"):
            class Konqueror:
                """Controller for the KDE File Manager (kfm, or Konqueror).

                See http://developer.kde.org/documentation/other/kfmclient.html
                for more information on the Konqueror remote-control interface.

                """
                def __init__(self):
                    if _iscommand("konqueror"):
                        self.name = self.basename = "konqueror"
                    else:
                        self.name = self.basename = "kfm"

                def _remote(self, action):
                    cmd = "kfmclient %s >/dev/null 2>&1" % action
                    rc = os.system(cmd)
                    if rc:
                        import time
                        if self.basename == "konqueror":
                            os.system(self.name + " --silent &")
                        else:
                            os.system(self.name + " -d &")
                        time.sleep(PROCESS_CREATION_DELAY)
                        rc = os.system(cmd)
                    return not rc

                def open(self, url, new=1, autoraise=1):
                    # XXX Currently I know no way to prevent KFM from
                    # opening a new win.
                    self._remote("openURL %s" % url)

                # Deprecated.  May be removed in 2.1.
                open_new = open

            register("kfm", Konqueror, Konqueror())

        # Grail, the Python browser.
        if _iscommand("grail"):
            class Grail:
                # There should be a way to maintain a connection to
                # Grail, but the Grail remote control protocol doesn't
                # really allow that at this point.  It probably neverwill!
                def _find_grail_rc(self):
                    import glob
                    import pwd
                    import socket
                    import tempfile
                    tempdir = os.path.join(tempfile.gettempdir(),
                                           ".grail-unix")
                    user = pwd.getpwuid(_os.getuid())[0]
                    filename = os.path.join(tempdir, user + "-*")
                    maybes = glob.glob(filename)
                    if not maybes:
                        return None
                    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
                    for fn in maybes:
                        # need to PING each one until we find one that's live
                        try:
                            s.connect(fn)
                        except socket.error:
                            # no good; attempt to clean it out, but don't fail:
                            try:
                                os.unlink(fn)
                            except IOError:
                                pass
                        else:
                            return s

                def _remote(self, action):
                    s = self._find_grail_rc()
                    if not s:
                        return 0
                    s.send(action)
                    s.close()
                    return 1

                def open(self, url, new=0, autoraise=1):
                    if new:
                        self._remote("LOADNEW " + url)
                    else:
                        self._remote("LOAD " + url)

                # Deprecated.  May be removed in 2.1.
                def open_new(self, url):
                    self.open(url, 1)

            register("grail", Grail, None)

#
# Platform support for Windows
#

if sys.platform[:3] == "win":
    _tryorder = ("netscape", "windows-default")

    class WindowsDefault:
        def open(self, url, new=0, autoraise=1):
            os.startfile(url)

        def open_new(self, url):        # Deprecated.  May be removed in 2.1.
            self.open(url)

    register("windows-default", WindowsDefault)

#
# Platform support for MacOS
#

try:
    import ic
except ImportError:
    pass
else:
    class InternetConfig:
        def open(self, url, new=0, autoraise=1):
            ic.launchurl(url)

        def open_new(self, url):        # Deprecated.  May be removed in 2.1.
            self.open(url)

    # internet-config is the only supported controller on MacOS,
    # so don't mess with the default!
    _tryorder = ("internet-config")
    register("internet-config", InternetConfig)

# OK, now that we know what the default preference orders for each
# platform are, allow user to override them with the BROWSER variable.
#
if os.environ.has_key("BROWSER"):
    # It's the user's responsibility to register handlers for any unknown
    # browser referenced by this value, before calling open().
    _tryorder = os.environ["BROWSER"].split(":")
else:
    # Optimization: filter out alternatives that aren't available, so we can
    # avoid has_key() tests at runtime.  (This may also allow some unused
    # classes and class-instance storage to be garbage-collected.)
    _tryorder = filter(lambda x: _browsers.has_key(x.lower())
                       or x.find("%s") > -1, _tryorder)

# end
