#!/usr/bin/env python
"""
Dependency manager for llvm CI builds.

We have complex dependencies for some of our CI builds. This will serve
as a system to help document and enforce them.

Developer notes:

- We are trying to keep package dependencies to a minimum in this project. So it
does not require an installer. It should be able to be run as a stand alone script
when checked out of VCS. So, don't import anything not in the Python standard
library.

"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import argparse
import collections
import json
import os
import platform
import re
import subprocess
import sys

try:
    # noinspection PyUnresolvedReferences
    from typing import List, Text, Union, Dict, Type, Optional  # noqa
except ImportError as e:
    pass  # Not really needed at runtime, so okay to not have installed.


VERSION = '0.1'
"""We have a built in version check, so we can require specific features and fixes."""


class Version(object):
    """Model a version number, which can be compared to another version number.

    Keeps a nice looking text version around as well for printing.

    This abstraction exists to make some of the more complex comparisons easier,
    as well as collecting and printing versions.

    In the future, we might want to have some different comparison,
    for instance, 4.0 == 4.0.0 -> True.

    """

    def __init__(self, text):
        """Create a version from a . separated version string."""
        self.text = text
        self.numeric = [int(d) for d in text.split(".")]

    def __gt__(self, other):
        """Compare the numeric representation of the version."""
        return self.numeric.__gt__(other.numeric)

    def __lt__(self, other):
        """Compare the numeric representation of the version."""
        return self.numeric.__lt__(other.numeric)

    def __eq__(self, other):
        """Compare the numeric representation of the version."""
        return self.numeric.__eq__(other.numeric)

    def __le__(self, other):
        """Compare the numeric representation of the version."""
        return self.numeric.__le__(other.numeric)

    def __ge__(self, other):
        """Compare the numeric representation of the version."""
        return self.numeric.__ge__(other.numeric)

    def __repr__(self):
        """Print the original text representation of the Version."""
        return "v{}".format(self.text)


class Dependency(object):
    """Dependency Abstract base class."""

    def __init__(self, line, str_kind):
        """Save line information.

        :param line: A parsed Line object that contains the raw dependency deceleration.
        :param str_kind: The determined kind of the Dependency.
        """
        # type: (Line, Text) -> object
        self.line = line
        self.str_kind = str_kind
        self.installed_version = None

    def parse(self):
        """Read the input line and prepare to verify this dependency.

        Raise a MalformedDependencyError if three is something wrong.

        Should return nothing, but get the dependency ready for verification.
        """
        raise NotImplementedError()

    def verify(self):
        # type: () -> bool
        """Determine if this dependency met.

        :returns: True when the dependency is met, otherwise False.
        """
        raise NotImplementedError()

    def inject(self):
        """If possible, modify the system to meet the dependency."""
        raise NotImplementedError()

    def verify_and_act(self):
        """Parse, then verify and trigger pass or fail.

        Extract that out here, so we don't duplicate the logic in the subclasses.
        """
        met = self.verify()
        if met:
            self.verify_pass()
        else:
            self.verify_fail()

    def verify_fail(self):
        """When dependency is not met, raise an exception.

        This is the default behavior; but I want the subclasses to be able
        to change it.
        """
        raise MissingDependencyError(self, self.installed_version)

    def verify_pass(self):
        """Print a nice message that the dependency is met.

        I'm not sure we even want to print this, but we will for now. It might
        be to verbose.  Subclasses should override this if wanted.
        """
        print("Dependency met", str(self))


class MalformedDependency(Exception):
    """Raised when parsing a dependency directive fails.

    This is situations like the regexes not matching, or part of the dependency directive missing.

    Should probably record more useful stuff, but Exception.message is set. So we can print it later.
    """

    pass


def brew_cmd(command):
    # type: (List[Text]) -> List[Dict[Text, object]]
    """Help run a brew command, and parse the output.

    Brew has a json output option which we use.  Run the command and parse the stdout
    as json and return the result.
    :param command: The brew command to execute, and parse the output of.
    :return:
    """
    assert "--json=v1" in command, "Must pass JSON arg so we can parse the output."
    out = subprocess.check_output(command).decode("utf-8")
    brew_info = json.loads(out)
    return brew_info


class MissingDependencyError(Exception):
    """Fail verification with one of these when we determine a dependency is not met.

    For each dependency, we will print a useful message with the dependency line as well as the
    reason it was not matched.
    """

    def __init__(self, dependency, installed=None):
        # type: (Dependency, Optional[Text]) -> None
        """Raise when a dependency is not met.

        This exception can be printed as the error message.

        :param dependency: The dependency that is not being met.
        :param installed: what was found to be installed instead.
        """
        # type: (Dependency, Union[Text, Version]) -> None
        super(MissingDependencyError, self).__init__()
        self.dependency = dependency
        self.installed = installed

    def __str__(self):
        """For now, we will just print these as our error message."""
        return "missing dependency: {}, found {} installed, requested from {}".format(self.dependency,
                                                                                      self.installed,
                                                                                      self.dependency.line)


def check_version(installed, operator, requested):
    """Check that the installed version does the operator of the requested.

    :param installed: The installed Version of the requirement.
    :param operator: the text operator (==, <=, >=)
    :param requested: The requested Version of the requirement.
    :return: True if the requirement is satisfied.
    """
    # type: (Version, Text, Version) -> bool

    dependency_met = False
    if operator == "==" and installed == requested:
        dependency_met = True
    if operator == "<=" and installed <= requested:
        dependency_met = True
    if operator == ">=" and installed >= requested:
        dependency_met = True
    return dependency_met


class ConMan(Dependency):
    """Version self-check of this tool.

    In case we introduce something in the future, the dep files can
    be made to depend on a specific version of this tool.  We will
    increment the versions manually.

    """

    conman_re = re.compile(r'(?P<command>\w+)\s+(?P<operator>>=|<=|==)\s*(?P<version_text>[\d.-_]+)')
    """For example: config_manager <= 0.1"""

    def __init__(self, line, kind):
        """Check that this tool is up to date."""
        super(ConMan, self).__init__(line, kind)
        self.command = None
        self.operator = None
        self.version = None
        self.version_text = None
        self.installed_version = None

    def parse(self):
        """Parse dependency."""
        text = self.line.text
        match = self.conman_re.match(text)
        if not match:
            raise MalformedDependency("Expression does not compile in {}: {}".format(self.__class__.__name__,
                                                                                     self.line))
        self.__dict__.update(match.groupdict())

        self.version = Version(self.version_text)

    def verify(self):
        """Verify the version of this tool."""
        self.installed_version = Version(VERSION)

        return check_version(self.installed_version, self.operator, self.version)

    def inject(self):
        """Can't really do much here."""
        pass

    def __str__(self):
        """Show as dependency and version."""
        return "{} {}".format(self.str_kind, self.version)


class HostOSVersion(Dependency):
    """Use Python's platform module to get host OS information and verify.

    Wew can only verify, but not inject for host OS version.
    """

    conman_re = re.compile(r'(?P<command>\w+)\s+(?P<operator>>=|<=|==)\s*(?P<version_text>[\d.-_]+)')

    def __init__(self, line, kind):
        """Parse and Verify host OS version using Python's platform module.

        :param line: Line with teh Dependencies deceleration.
        :param kind: the dependency kind that was detected by the parser.
        """
        # type: (Line, Text) -> None
        super(HostOSVersion, self).__init__(line, kind)
        self.command = None
        self.operator = None
        self.version = None
        self.version_text = None
        self.installed_version = None

    def parse(self):
        """Parse dependency."""
        text = self.line.text
        match = self.conman_re.match(text)
        if not match:
            raise MalformedDependency("Expression does not compile in {}: {}".format(self.__class__.__name__,
                                                                                     self.line))
        self.__dict__.update(match.groupdict())

        self.version = Version(self.version_text)

    def verify(self):
        """Verify the request host OS version holds."""
        self.installed_version = Version(platform.mac_ver()[0])

        return check_version(self.installed_version, self.operator, self.version)

    def inject(self):
        """Can't change the host OS version, so not much to do here."""
        pass

    def __str__(self):
        """For printing in error messages."""
        return "{} {}".format(self.str_kind, self.version)


class Brew(Dependency):
    """Verify and Inject brew package dependencies."""

    # brew <package> <operator> <version>.  Operator may not have spaces around it.
    brew_re = re.compile(r'(?P<command>\w+)\s+(?P<package>\w+)\s*(?P<operator>>=|<=|==)\s*(?P<version_text>[\d.-_]+)')

    def __init__(self, line, kind):
        # type: (Line, Text) -> None
        """Parse and verify brew package is installed.

        :param line: the Line with the deceleration of the dependency.
        :param kind: the detected dependency kind.
        """
        super(Brew, self).__init__(line, kind)
        self.command = None
        self.operator = None
        self.package = None
        self.version = None
        self.version_text = None
        self.installed_version = None

    def parse(self):
        """Parse this dependency."""
        text = self.line.text
        match = self.brew_re.match(text)
        if not match:
            raise MalformedDependency("Expression does not compile in {}: {}".format(self.__class__.__name__,
                                                                                     self.line))
        self.__dict__.update(match.groupdict())

        self.version = Version(self.version_text)

    def verify(self):
        """Verify the packages in brew match this dependency."""
        try:
            brew_package_config = brew_cmd(['/usr/local/bin/brew', 'info', self.package, "--json=v1"])
        except OSError:
            raise MissingDependencyError(self, "Can't find brew command")
        version = None
        for brew_package in brew_package_config:
            name = brew_package['name']
            linked_keg = brew_package["linked_keg"]

            install_info = brew_package.get('installed')
            for versions in install_info:
                if linked_keg == versions['version']:
                    version = versions['version']
            if name == self.package:
                break
        if not version:
            # The package is not installed at all.
            raise MissingDependencyError(self, "nothing")
        self.installed_version = Version(version)
        return check_version(self.installed_version, self.operator, self.version)

    def inject(self):
        """Not implemented."""
        raise NotImplementedError()

    def __str__(self):
        """Dependency kind, package and version, for printing in error messages."""
        return "{} {} {}".format(self.str_kind, self.package, self.version)


class Xcode(Dependency):
    """Verify and Inject Xcode version dependencies."""

    # xcode <operator> <version>.  Operator may not have spaces around it.
    xcode_dep_re = re.compile(r'(?P<command>\w+)\s+(?P<operator>>=|<=|==)\s*(?P<version_text>[\d.-_]+)')

    def __init__(self, line, kind):
        # type: (Line, Text) -> None
        """Parse and xcode version installed.

        :param line: the Line with the deceleration of the dependency.
        :param kind: the detected dependency kind.
        """
        super(Xcode, self).__init__(line, kind)
        self.command = None
        self.operator = None
        self.version = None
        self.version_text = None
        self.installed_version = None

    def parse(self):
        """Parse this dependency."""
        text = self.line.text
        match = self.xcode_dep_re.match(text)
        if not match:
            raise MalformedDependency("Expression does not compile in {}: {}".format(self.__class__.__name__,
                                                                                     self.line))
        self.__dict__.update(match.groupdict())

        self.version = Version(self.version_text)

    def verify(self):
        """Verify the installed Xcode matches this dependency."""
        installed_version_output = subprocess.check_output(['/usr/bin/xcrun', 'xcodebuild', "-version"]).decode("utf-8")
        installed_version_re = re.compile(r"^Xcode\s(?P<version_text>[\d/.]+)")
        match = installed_version_re.match(installed_version_output)
        if not match:
            raise MissingDependencyError(self, "Did not find Xcode version in output:" + installed_version_output)
        version = match.groupdict().get('version_text')
        if not version:
            # The package is not installed at all.
            raise AssertionError("No version text found.")
        self.installed_version = Version(version)
        return check_version(self.installed_version, self.operator, self.version)

    def inject(self):
        """Not implemented."""
        raise NotImplementedError()

    def __str__(self):
        """Dependency kind, package and version, for printing in error messages."""
        return "{} {}".format(self.str_kind, self.version)


class Sdk(Dependency):
    """Verify and Inject Sdk version dependencies."""

    # sdk <operator> <version>.  Operator may not have spaces around it.
    sdk_dep_re = re.compile(r'(?P<command>\w+)\s+(?P<sdk>[\w/.]+)\s*'
                            r'(?P<operator>>=|<=|==)\s*(?P<version_text>[\d.-_]+)')

    def __init__(self, line, kind):
        # type: (Line, Text) -> None
        """Parse and sdk version installed.

        :param line: the Line with the deceleration of the dependency.
        :param kind: the detected dependency kind.
        """
        super(Sdk, self).__init__(line, kind)
        self.command = None
        self.sdk = None
        self.operator = None
        self.version = None
        self.version_text = None
        self.installed_version = None

    def parse(self):
        """Parse this dependency."""
        text = self.line.text
        match = self.sdk_dep_re.match(text)
        if not match:
            raise MalformedDependency("Expression does not compile in {}: {}".format(self.__class__.__name__,
                                                                                     self.line))
        self.__dict__.update(match.groupdict())

        self.version = Version(self.version_text)

    def verify(self):
        """Verify the installed Sdk matches this dependency."""
        installed_version_output = subprocess.check_output(['/usr/bin/xcrun', 'xcodebuild', "-showsdks"]).decode("utf-8")
        installed_version_re = re.compile(r".*-sdk\s+(?P<sdk_text>\S+)")

        matches = [installed_version_re.match(l).groupdict()['sdk_text']
                   for l in installed_version_output.split('\n') if installed_version_re.match(l)]

        if not matches:
            raise MissingDependencyError(self, "Did not find Sdk version in output:" + installed_version_output)

        extract_version_names = re.compile(r'(?P<pre>\D*)(?P<version_text>[\d+/.]*)(?P<post>.*)')

        sdks = [extract_version_names.match(sdk_text).groupdict()
                for sdk_text in matches if extract_version_names.match(sdk_text)]

        installed_sdks = collections.defaultdict(list)
        for sdk in sdks:
            name = sdk['pre']
            if sdk.get('post'):
                name += "." + sdk.get('post')
            if sdk.get('version_text'):
                version = Version(sdk['version_text'].rstrip('.'))
            else:
                continue
            installed_sdks[name].append(version)

        if self.sdk not in installed_sdks.keys():
            raise MissingDependencyError(self, "{} not found in installed SDKs.".format(self.sdk))

        self.installed_version = installed_sdks[self.sdk]

        satisfied = [check_version(s, self.operator, self.version) for s in self.installed_version]
        return any(satisfied)

    def inject(self):
        """Not implemented."""
        raise NotImplementedError()

    def __str__(self):
        """Dependency kind, package and version, for printing in error messages."""
        return "{} {}".format(self.str_kind, self.version)


class Pip(Dependency):
    """Verify and Inject pip package dependencies."""

    # pip <package> <operator> <version>.  Operator may not have spaces around it.
    pip_re = re.compile(r'(?P<command>\w+)\s+(?P<package>\w+)\s*(?P<operator>>=|<=|==)\s*(?P<version_text>[\d.-_]+)')

    def __init__(self, line, kind):
        # type: (Line, Text) -> None
        """Parse and verify pip package is installed.

        :param line: the Line with the deceleration of the dependency.
        :param kind: the detected dependency kind.
        """
        super(Pip, self).__init__(line, kind)
        self.command = None
        self.operator = None
        self.package = None
        self.version = None
        self.version_text = None
        self.installed_version = None

    def parse(self):
        """Parse this dependency."""
        text = self.line.text
        match = self.pip_re.match(text)
        if not match:
            raise MalformedDependency("Expression does not compile in {}: {}".format(self.__class__.__name__,
                                                                                     self.line))
        self.__dict__.update(match.groupdict())

        self.version = Version(self.version_text)

    def verify(self):
        """Verify the packages in pip match this dependency."""

        try:
            pip_version = subprocess.check_output([sys.executable, "-m", "pip", "--version"]).decode("utf-8")
            pip_tokens = pip_version.split()
            assert pip_tokens[0] == "pip"
            pip_version = Version(pip_tokens[1])

            if pip_version < Version("9.0.0"):
                raise MissingDependencyError(self, "Version of pip too old.")

            pip_package_config = json.loads(subprocess.check_output([sys.executable,
                                                                     "-m",
                                                                     "pip",
                                                                     "list",
                                                                     "--format=json"]).decode("utf-8"))
        except (subprocess.CalledProcessError, OSError):
            raise MissingDependencyError(self, "Cannot find pip")

        installed = {p['name']: p['version'] for p in pip_package_config}  # type: Dict[Text, Text]

        package = installed.get(self.package)

        if not package:
            # The package is not installed at all.
            raise MissingDependencyError(self, "not in package list")
        self.installed_version = Version(package)
        return check_version(self.installed_version, self.operator, self.version)

    def inject(self):
        """Not implemented."""
        raise NotImplementedError()

    def __str__(self):
        """Dependency kind, package and version, for printing in error messages."""
        return "{} {} {}".format(self.str_kind, self.package, self.version)


class Device(Dependency):
    """Verify correct device is attached to this machine."""

    # device somelongudidstring.
    # We will filter dashes if they are added.
    device_re = re.compile(r'(?P<command>\w+)\s+(?P<udid>.*)')

    def __init__(self, line, kind):
        # type: (Line, Text) -> None
        """Parse and verify device is attached.

        :param line: the Line with the deceleration of the dependency.
        :param kind: the detected dependency kind.
        """
        super(Device, self).__init__(line, kind)
        self.command = None
        self.udid = None
        self.installed_version = None

    def parse(self):
        """Parse this dependency."""
        text = self.line.text
        match = self.device_re.match(text)
        if not match:
            raise MalformedDependency("Expression does not compile in {}: {}".format(self.__class__.__name__,
                                                                                     self.line))
        self.__dict__.update(match.groupdict())
        # Sometimes people put dashes in these, lets not compare with dashes.
        self.udid = self.udid.replace("-", "")

    def verify(self):
        """Verify the device is attached."""

        try:
            instruments_output = subprocess.check_output(["xcrun", "instruments", "-s", "devices"]).decode("utf-8")
        except (subprocess.CalledProcessError, OSError):
            raise MissingDependencyError(self, "Cannot find instruments")
        # Convert udids with dashes to without for comparison.
        cleaned_instruments_output = instruments_output.replace(u"-", u"")
        if self.udid not in cleaned_instruments_output:
            # The device is not in instruments.
            raise MissingDependencyError(self, "")
        return True

    def inject(self):
        """Not implemented."""
        raise NotImplementedError()

    def __str__(self):
        """Dependency kind, package and version, for printing in error messages."""
        return "{} {} {}".format(self.str_kind, self.udid, "")


dependencies_implementations = {'brew': Brew,
                                'os_version': HostOSVersion,
                                'config_manager': ConMan,
                                'xcode': Xcode,
                                'sdk': Sdk,
                                'pip': Pip,
                                'device': Device,
                                }


def dependency_factory(line):
    """Given a line, create a concrete dependency for it.

    :param line: The line with the dependency info
    :return: Some subclass of Dependency, based on what was in the line.
    """
    # type: Text -> Dependency
    kind = line.text.split()[0]
    try:
        return dependencies_implementations[kind](line, kind)
    except KeyError:
        raise MalformedDependency("Don't know about {} kind of dependency.".format(kind))


class Line(object):
    """A preprocessed line. Understands file and line number as well as comments."""

    def __init__(self, filename, line_number, text, comment):
        # type: (Text, int, Text, Text) -> None
        """Raw Line information, split into the dependency deceleration and comment.

        :param filename: the input filename.
        :param line_number: the line number in the input file.
        :param text: Non-comment part of the line.
        :param comment: Text from the comment part of the line if any.
        """
        self.filename = filename
        self.line_number = line_number
        self.text = text
        self.comment = comment

    def __repr__(self):
        """Reconstruct the line for pretty printing."""
        return "{}:{}: {}{}".format(os.path.basename(self.filename),
                                    self.line_number,
                                    self.text,
                                    " # " + self.comment if self.comment else "")


# For stripping comments out of lines.
comment_re = re.compile(r'(?P<main_text>.*)#(?P<comment>.*)')


# noinspection PyUnresolvedReferences
def _parse_dep_file(lines, filename):
    # type: (List[Text], Text) -> List[Line]
    process_lines = []
    for num, text in enumerate(lines):
        if "#" in text:
            bits = comment_re.match(text)
            main_text = bits.groupdict().get('main_text')
            comment = bits.groupdict().get('comment')
        else:
            main_text = text
            comment = None
        if main_text:
            main_text = main_text.strip()
        if comment:
            comment = comment.strip()
        process_lines.append(Line(filename, num, main_text, comment))

    return process_lines


def parse_dependencies(file_names):
    """Program logic: read files, verify dependencies.

    For each input file, read lines and create dependencies. Verify each dependency.

    :param file_names: files to read dependencies from.
    :return: The list of dependencies, each verified.
    """
    # type: (List[Text]) -> List[Type[Dependency]]
    preprocessed_lines = []
    for file_name in file_names:
        with open(file_name, 'r') as f:
            lines = f.readlines()
            preprocessed_lines.extend(_parse_dep_file(lines, file_name))

    dependencies = [dependency_factory(l) for l in preprocessed_lines if l.text]
    [d.parse() for d in dependencies]
    for d in dependencies:
        try:
            met = d.verify()
            if met:
                d.verify_pass()
            else:
                d.verify_fail()

        except MissingDependencyError as exec_info:
            print("Error:", exec_info)

    return dependencies


def main():
    """Parse arguments and trigger dependency verification."""
    parser = argparse.ArgumentParser(description='Verify and install dependencies.')
    parser.add_argument('command', help="What to do.")

    parser.add_argument('dependencies',  nargs='+', help="Path to dependency files.")

    args = parser.parse_args()

    full_file_paths = [os.path.abspath(path) for path in args.dependencies]

    parse_dependencies(full_file_paths)

    return True


if __name__ == '__main__':
    main()
