"""Parser for .test files"""
from lit.TestRunner import parseIntegratedTestScriptCommands, \
        getDefaultSubstitutions, applySubstitutions
from litsupport import shellcommand
import logging


def _parseShellCommand(script, ln):
    # Trim trailing whitespace.
    ln = ln.rstrip()

    # Collapse lines with trailing '\\'.
    if script and script[-1][-1] == '\\':
        script[-1] = script[-1][:-1] + ln
    else:
        script.append(ln)


def parse(context, filename):
    """Parse a .test file as used in the llvm test-suite.
    The file comporises of a number of lines starting with RUN: and VERIFY:
    specifying shell commands to run the benchmark and verifying the result.
    Returns a tuple with two arrays for the run and verify commands."""
    # Collect the test lines from the script.
    preparescript = []
    runscript = []
    verifyscript = []
    metricscripts = {}
    # Note that we keep both "RUN" and "RUN:" in the list to stay compatible
    # with older lit versions.
    keywords = ['PREPARE:', 'PREPARE', 'RUN:', 'RUN', 'VERIFY:', 'VERIFY',
                'METRIC:', 'METRIC']
    for line_number, command_type, ln in \
            parseIntegratedTestScriptCommands(filename, keywords):
        if command_type.startswith('PREPARE'):
            _parseShellCommand(preparescript, ln)
        elif command_type.startswith('RUN'):
            _parseShellCommand(runscript, ln)
        elif command_type.startswith('VERIFY'):
            _parseShellCommand(verifyscript, ln)
        elif command_type.startswith('METRIC'):
            metric, ln = ln.split(':', 1)
            metricscript = metricscripts.setdefault(metric.strip(), list())
            _parseShellCommand(metricscript, ln)
        else:
            raise ValueError("unknown script command type: %r" % (
                             command_type,))

    # Verify the script contains a run line.
    if runscript == []:
        raise ValueError("Test has no RUN: line!")

    # Check for unterminated run lines.
    for script in preparescript, runscript, verifyscript:
        if script and script[-1][-1] == '\\':
            raise ValueError("Test has unterminated RUN/VERIFY lines " +
                             "(ending with '\\')")

    # Apply the usual lit substitutions (%s, %S, %p, %T, ...)
    outfile = context.tmpBase + ".out"
    substitutions = getDefaultSubstitutions(context.test, context.tmpDir,
                                            context.tmpBase)
    substitutions += [('%o', outfile)]
    preparescript = applySubstitutions(preparescript, substitutions)
    runscript = applySubstitutions(runscript, substitutions)
    verifyscript = applySubstitutions(verifyscript, substitutions)
    metricscripts = {k: applySubstitutions(v, substitutions)
                     for k, v in metricscripts.items()}

    # Put things into the context
    context.parsed_preparescript = preparescript
    context.parsed_runscript = runscript
    context.parsed_verifyscript = verifyscript
    context.parsed_metricscripts = metricscripts
    context.executable = shellcommand.getMainExecutable(context)
    if not context.executable:
        logging.error("Could not determine executable name in %s" % filename)
