import os
import re

import lit.util

expr = re.compile(r"^(\\)?((\| )?)\W+b(\S+)\\b\W*$")
wordifier = re.compile(r"(\W*)(\b[^\b]+\b)")


class FindTool(object):
    def __init__(self, name):
        self.name = name

    def resolve(self, config, dirs):
        # Check for a user explicitely overriding a tool.  This allows:
        #     llvm-lit -D llc="llc -enable-misched -verify-machineinstrs"
        command = config.lit_config.params.get(self.name)
        if command is None:
            # Then check out search paths.
            command = lit.util.which(self.name, dirs)
            if not command:
                return None

        if self.name == 'llc' and os.environ.get('LLVM_ENABLE_MACHINE_VERIFIER') == '1':
            command += ' -verify-machineinstrs'
        elif self.name == 'llvm-go':
            exe = getattr(config.config, 'go_executable', None)
            if exe:
                command += ' go=' + exe
        return command


class ToolSubst(object):
    """String-like class used to build regex substitution patterns for llvm
    tools.

    Handles things like adding word-boundary patterns, and filtering
    characters from the beginning an end of a tool name

    """

    def __init__(self, key, command=None, pre=r'.-^/\<', post='-.', verbatim=False,
                 unresolved='warn', extra_args=None):
        """Construct a ToolSubst.

        key: The text which is to be substituted.

        command: The command to substitute when the key is matched.  By default,
        this will treat `key` as a tool name and search for it.  If it is
        a string, it is intereprted as an exact path.  If it is an instance of
        FindTool, the specified tool name is searched for on disk.

        pre: If specified, the substitution will not find matches where
        the character immediately preceding the word-boundary that begins
        `key` is any of the characters in the string `pre`.

        post: If specified, the substitution will not find matches where
        the character immediately after the word-boundary that ends `key`
        is any of the characters specified in the string `post`.

        verbatim: If True, `key` is an exact regex that is passed to the
        underlying substitution

        unresolved: Action to take if the tool substitution cannot be
        resolved.  Valid values:
            'warn' - log a warning but add the substitution anyway.
            'fatal' - Exit the test suite and log a fatal error.
            'break' - Don't add any of the substitutions from the current
                      group, and return a value indicating a failure.
            'ignore' - Don't add the substitution, and don't log an error

        extra_args: If specified, represents a list of arguments that will be
        appended to the tool's substitution.

        explicit_path: If specified, the exact path will be used as a substitution.
        Otherwise, the tool will be searched for as if by calling which(tool)

        """
        self.unresolved = unresolved
        self.extra_args = extra_args
        self.key = key
        self.command = command if command is not None else FindTool(key)
        self.was_resolved = False
        if verbatim:
            self.regex = key
            return

        def not_in(chars, where=''):
            if not chars:
                return ''
            pattern_str = '|'.join(re.escape(x) for x in chars)
            return r'(?{}!({}))'.format(where, pattern_str)

        def wordify(word):
            match = wordifier.match(word)
            introducer = match.group(1)
            word = match.group(2)
            return introducer + r'\b' + word + r'\b'

        self.regex = not_in(pre, '<') + wordify(key) + not_in(post)

    def resolve(self, config, search_dirs):
        # Extract the tool name from the pattern.  This relies on the tool
        # name being surrounded by \b word match operators.  If the
        # pattern starts with "| ", include it in the string to be
        # substituted.

        tool_match = expr.match(self.regex)
        if not tool_match:
            return None

        tool_pipe = tool_match.group(2)
        tool_name = tool_match.group(4)

        if isinstance(self.command, FindTool):
            command_str = self.command.resolve(config, search_dirs)
        else:
            command_str = str(self.command)

        if command_str:
            if self.extra_args:
                command_str = ' '.join([command_str] + self.extra_args)
        else:
            if self.unresolved == 'warn':
                # Warn, but still provide a substitution.
                config.lit_config.note(
                    'Did not find ' + tool_name + ' in %s' % search_dirs)
                command_str = os.path.join(
                    config.config.llvm_tools_dir, tool_name)
            elif self.unresolved == 'fatal':
                # The function won't even return in this case, this leads to
                # sys.exit
                config.lit_config.fatal(
                    'Did not find ' + tool_name + ' in %s' % search_dirs)
            elif self.unresolved == 'break':
                # By returning a valid result with an empty command, the
                # caller treats this as a failure.
                pass
            elif self.unresolved == 'ignore':
                # By returning None, the caller just assumes there was no
                # match in the first place.
                return None
            else:
                raise 'Unexpected value for ToolSubst.unresolved'
        if command_str:
            self.was_resolved = True
        return (self.regex, tool_pipe, command_str)
