import logging
import os
import platform
import re
import stat
from abc import ABCMeta, abstractmethod
from ConfigParser import RawConfigParser
from distutils.spawn import find_executable

from utils import call, get, untar, unzip

logger = logging.getLogger(__name__)

uname = platform.uname()

def path(path, exe):
    path = path.replace("/", os.path.sep)
    if exe and uname[0] == "Windows":
        path += ".exe"
    return path


class Browser(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def install(self, dest=None):
        return NotImplemented

    @abstractmethod
    def install_webdriver(self):
        return NotImplemented

    @abstractmethod
    def version(self):
        return NotImplemented

    @abstractmethod
    def requirements(self):
        """Name of the browser-specific wptrunner requirements file"""
        return NotImplemented

    def prepare_environment(self):
        """Do any additional setup of the environment required to start the
           browser successfully
        """
        pass


class Firefox(Browser):
    """Firefox-specific interface.

    Includes installation, webdriver installation, and wptrunner setup methods.
    """

    product = "firefox"
    binary = "firefox/firefox"
    platform_ini = "firefox/platform.ini"
    requirements = "requirements_firefox.txt"


    def platform_string(self):
        platform = {
            "Linux": "linux",
            "Windows": "win",
            "Darwin": "mac"
        }.get(uname[0])

        if platform is None:
            raise ValueError("Unable to construct a valid Firefox package name for current platform")

        if platform == "linux":
            bits = "-%s" % uname[-1]
        elif platform == "win":
            bits = "64" if uname[-1] == "x86_64" else "32"
        else:
            bits = ""

        return "%s%s" % (platform, bits)

    def platform_string_geckodriver(self):
        platform = {
            "Linux": "linux",
            "Windows": "win",
            "Darwin": "macos"
        }.get(uname[0])

        if platform is None:
            raise ValueError("Unable to construct a valid Geckodriver package name for current platform")

        if platform in ("linux", "win"):
            bits = "64" if uname[-1] == "x86_64" else "32"
        else:
            bits = ""

        return "%s%s" % (platform, bits)

    def latest_nightly_listing(self):
        return get("https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/")

    def get_from_nightly(self, pattern):
        index = self.latest_nightly_listing()
        filename = re.compile(pattern).search(index.text).group(1)
        return get("https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/%s" %
                   filename)

    def install(self, dest=None):
        """Install Firefox."""
        if dest is None:
            dest = os.getcwd()

        resp = self.get_from_nightly("<a[^>]*>(firefox-\d+\.\d(?:\w\d)?.en-US.%s\.tar\.bz2)" % self.platform_string())
        untar(resp.raw, dest=dest)
        return find_executable("firefox", os.path.join(dest, "firefox"))

    def find_binary(self, path=None):
        return find_executable("firefox", path)

    def find_certutil(self):
        path = find_executable("certutil")
        if path is None:
            return None
        if os.path.splitdrive(path)[1].split(os.path.sep) == ["", "Windows", "system32", "certutil.exe"]:
            return None
        return path

    def find_webdriver(self):
        return find_executable("geckodriver")

    def install_certutil(self, dest=None):
        # TODO: this doesn't really work because it just gets the binary, and is missing the
        # libnss3 library. Getting that means either downloading the corresponding Firefox
        # and extracting the library (which is hard on mac becase DMG), or maybe downloading from
        # nss's treeherder builds?
        if dest is None:
            dest = os.pwd

        # Don't create a path like bin/bin/certutil
        split = os.path.split(dest)
        if split[1] == "bin":
            dest = split[0]

        resp = self.get_from_nightly(
            "<a[^>]*>(firefox-\d+\.\d(?:\w\d)?.en-US.%s\.common\.tests.zip)</a>" % self.platform_string())
        bin_path = path("bin/certutil", exe=True)
        unzip(resp.raw, dest=dest, limit=[bin_path])

        return os.path.join(dest, bin_path)

    def install_prefs(self, dest=None):
        if dest is None:
            dest = os.pwd

        dest = os.path.join(dest, "profiles")
        if not os.path.exists(dest):
            os.makedirs(dest)
        with open(os.path.join(dest, "prefs_general.js"), "wb") as f:
            resp = get("https://hg.mozilla.org/mozilla-central/raw-file/tip/testing/profiles/prefs_general.js")
            f.write(resp.content)

        return dest

    def _latest_geckodriver_version(self):
        """Get and return latest version number for geckodriver."""
        # This is used rather than an API call to avoid rate limits
        tags = call("git", "ls-remote", "--tags", "--refs",
                    "https://github.com/mozilla/geckodriver.git")
        release_re = re.compile(".*refs/tags/v(\d+)\.(\d+)\.(\d+)")
        latest_release = 0
        for item in tags.split("\n"):
            m = release_re.match(item)
            if m:
                version = [int(item) for item in m.groups()]
                if version > latest_release:
                    latest_release = version
        assert latest_release != 0
        return "v%s.%s.%s" % tuple(str(item) for item in latest_release)

    def install_webdriver(self, dest=None):
        """Install latest Geckodriver."""
        if dest is None:
            dest = os.getcwd()

        version = self._latest_geckodriver_version()
        format = "zip" if uname[0] == "Windows" else "tar.gz"
        logger.debug("Latest geckodriver release %s" % version)
        url = ("https://github.com/mozilla/geckodriver/releases/download/%s/geckodriver-%s-%s.%s" %
               (version, version, self.platform_string_geckodriver(), format))
        if format == "zip":
            unzip(get(url).raw, dest=dest)
        else:
            untar(get(url).raw, dest=dest)
        return find_executable(os.path.join(dest, "geckodriver"))

    def version(self, root):
        """Retrieve the release version of the installed browser."""
        platform_info = RawConfigParser()

        with open(os.path.join(root, self.platform_ini), "r") as fp:
            platform_info.readfp(BytesIO(fp.read()))
            return "BuildID %s; SourceStamp %s" % (
                platform_info.get("Build", "BuildID"),
                platform_info.get("Build", "SourceStamp"))


class Chrome(Browser):
    """Chrome-specific interface.

    Includes installation, webdriver installation, and wptrunner setup methods.
    """

    product = "chrome"
    binary = "/usr/bin/google-chrome"
    requirements = "requirements_chrome.txt"

    def install(self, dest=None):
        raise NotImplementedError

    def platform_string(self):
        platform = {
            "Linux": "linux",
            "Windows": "win",
            "Darwin": "mac"
        }.get(uname[0])

        if platform is None:
            raise ValueError("Unable to construct a valid Chrome package name for current platform")

        if platform == "linux":
            bits = "64" if uname[-1] == "x86_64" else "32"
        elif platform == "mac":
            bits = "64"
        elif platform == "win":
            bits = "32"

        return "%s%s" % (platform, bits)

    def find_webdriver(self):
        return find_executable("chromedriver")

    def install_webdriver(self, dest=None):
        """Install latest Webdriver."""
        if dest is None:
            dest = os.pwd
        latest = get("http://chromedriver.storage.googleapis.com/LATEST_RELEASE").text.strip()
        url = "http://chromedriver.storage.googleapis.com/%s/chromedriver_%s.zip" % (latest,
                                                                                     self.platform_string())
        unzip(get(url).raw, dest)

        path = find_executable("chromedriver", dest)
        st = os.stat(path)
        os.chmod(path, st.st_mode | stat.S_IEXEC)
        return path

    def version(self, root):
        """Retrieve the release version of the installed browser."""
        output = call(self.binary, "--version")
        return re.search(r"[0-9\.]+( [a-z]+)?$", output.strip()).group(0)

    def prepare_environment(self):
        # https://bugs.chromium.org/p/chromium/issues/detail?id=713947
        logger.debug("DBUS_SESSION_BUS_ADDRESS %s" % os.environ.get("DBUS_SESSION_BUS_ADDRESS"))
        if "DBUS_SESSION_BUS_ADDRESS" not in os.environ:
            if find_executable("dbus-launch"):
                logger.debug("Attempting to start dbus")
                dbus_conf = subprocess.check_output(["dbus-launch"])
                logger.debug(dbus_conf)

                # From dbus-launch(1):
                #
                # > When dbus-launch prints bus information to standard output,
                # > by default it is in a simple key-value pairs format.
                for line in dbus_conf.strip().split("\n"):
                    key, _, value = line.partition("=")
                    os.environ[key] = value
            else:
                logger.critical("dbus not running and can't be started")
                sys.exit(1)


class Edge(Browser):
    """Edge-specific interface.

    Includes installation, webdriver installation, and wptrunner setup methods.
    """

    product = "edge"
    requirements = "requirements_edge.txt"

    def install(self, dest=None):
        raise NotImplementedError

    def find_webdriver(self):
        return find_executable("MicrosoftWebDriver")

    def install_webdriver(self, dest=None):
        """Install latest Webdriver."""
        raise NotImplementedError

    def version(self):
        raise NotImplementedError


class Servo(Browser):
    """Servo-specific interface.

    Includes installation, webdriver installation, and wptrunner setup methods.
    """

    product = "servo"
    requirements = "requirements_servo.txt"

    def install(self, dest=None):
        raise NotImplementedError

    def find_binary(self, path=None):
        return find_executable("servo")

    def find_webdriver(self):
        return None

    def install_webdriver(self):
        raise NotImplementedError

    def version(self, root):
        return None


class Sauce(Browser):
    """Sauce-specific interface.

    Includes installation, webdriver installation, and wptrunner setup methods.
    """

    product = "sauce"
    requirements = "requirements_sauce.txt"

    def install(self, dest=None):
        raise NotImplementedError

    def find_binary(self, path=None):
        return None

    def find_webdriver(self):
        return None

    def install_webdriver(self):
        raise NotImplementedError

    def version(self, root):
        return None
