"""Utilities for analyzing and manipulating shell commands."""
import shlex
import logging
import re
try:
        from shlex import quote  # python 3.3 and above
except:
        from pipes import quote  # python 3.2 and earlier


class ShellCommand:
    """This class represents a parsed shell command (a subset of posix shell
    commands; see parse()). The parsed form allows direct access to information
    like the executable name, working directory or the file to which
    stdin/stdout/stderr is redirected."""
    def __init__(self, executable=None, arguments=None):
        self.stdin = None
        self.stdout = None
        self.stderr = None
        self.executable = executable
        if arguments is None:
            arguments = []
        self.arguments = arguments
        self.workdir = None
        self.envvars = {}

    def toCommandline(self):
        """Transforms ShellCommand object to a posix shell commandline."""
        result = ""

        if self.workdir is not None:
            result += "cd %s && " % quote(self.workdir)

        res_list = [self.executable] + self.arguments
        result += " ".join(map(quote, res_list))

        envlist = []
        for key, value in self.envvars.items():
            result += "%s=%s " % (key, quote(value))

        if self.stdin is not None:
            result += " < %s" % quote(self.stdin)
        if self.stdout is not None:
            result += " > %s" % quote(self.stdout)
        if self.stderr is not None:
            result += " 2> %s" % quote(self.stderr)
        return result

    def wrap(self, new_executable, args):
        """Adds a prefix to the exeutable. Example:
        Prefixing `SOMVAR=42 cd mydir && mycmd -v > /dev/null` with `lldb --`
        becomes `SOMEVAR=42 cd mydir && lldb -- mycmd -v > /dev/null`."""
        self.arguments = args + [self.executable] + self.arguments
        self.executable = new_executable


# Tokens/keywords for shell command parsing, loosely modeled after posix
# specification for sh.
reserved_words = ['!', '{', '}', 'case', 'do', 'done', 'elif', 'else', 'esac',
                  'fi', 'for', 'if', 'in', 'then', 'until', 'while']

chaining_tokens = set([';', '&&', '||', '|', '&'])
unhandled_tokens = set([';;', '<<', '>>', '<&', '>&', '<>', '<<-', '>|', '(',
                        ')'])


def parse(commandline):
    """Parses a posix shell commandline to a ShellCommand object. This supports
    typical commandline with environment variables, input/output redirection
    and switching directories upfront. It does not support full posix shell
    and will throw an exception if the commandline uses unsupported features.
    """
    previous_commands = []
    result = ShellCommand()
    tokens = shlex.split(commandline)
    i = 0
    first_word = True
    while i < len(tokens):
        token = tokens[i]
        i += 1
        if token == '<' and i < len(tokens):
            result.stdin = tokens[i]
            i += 1
            continue
        if token == '>' and i < len(tokens):
            result.stdout = tokens[i]
            i += 1
            continue
        if token == '2>' and i < len(tokens):
            result.stderr = tokens[i]
            i += 1
            continue

        if first_word:
            # Is it an environment variable assignment?
            assignment = re.match('([A-Za-z_][A-Za-z_0-9]*)=(.*)', token)
            if assignment:
                result.envvars[assignment.group(1)] = assignment.group(2)
                continue
            # A reserved word?
            if token in reserved_words or token in unhandled_tokens:
                raise Exception("Reserved word '%s' not supported" % token)
            result.executable = token
            first_word = False
        else:
            if token in chaining_tokens:
                # Currently we only allow the special case of 'cd DIR ;'
                if (token == ';' or token == '&&') and \
                        result.executable == 'cd' and \
                        len(result.arguments) == 1:
                    newresult = ShellCommand()
                    newresult.workdir = result.arguments[0]
                    result = newresult
                    first_word = True
                    continue
                raise Exception("Command chaining not supported yet")
            if token in unhandled_tokens or token in reserved_words:
                raise Exception("Commandline with '%s' not supported yet" %
                                token)
            result.arguments.append(token)
    return result


# Some executables are just used to cleanup/prepare for a test run, ignore them
# here. This is from a time when there was no concept of a prepare script,
# it should not be necessary anymore for new test files.
_ignore_executables = set(['cd', 'rm', 'cp'])


def getMainExecutable(context):
    """Returns the main executable of the current run script. This skips over
    some commands typically used to setup a benchmark (see _ignore_executables)
    and returns the first executable found in the run script and prints a
    warning if more than one executable is found."""

    # Executable name already determined in a previous run?
    if hasattr(context, 'executable'):
        return context.executable

    executable = None
    for line in context.parsed_runscript:
        cmd = parse(line)
        if cmd.executable in _ignore_executables:
            continue
        # We only support one executable yet for collecting md5sums
        if cmd.executable != executable and executable is not None:
            logging.warning("More than one executable used in test %s",
                            context.test.getFullName())
        executable = cmd.executable
    if executable is None:
        logging.warning("No executable found for test %s",
                        context.test.getFullName())
    context.executable = executable
    return executable
