import re


def countFailedTests(output):
    """
    Given a Twisted trial log, find out how many tests passed, failed, etc.
    """
    res = {
        'total': None,
        'failures': 0,
        'errors': 0,
        'skips': 0,
        'expectedFailures': 0,
        'unexpectedSuccesses': 0,
    }

    # Find the "Ran X tests" output
    out = re.search(r'Ran (\d+) tests', output)

    if out is None:
        # No report found. Most probably the test were not executed due to a
        # high level error.
        res['failures'] = 1
        return res

    if out:
        res['total'] = int(out.group(1))

    chunk = output[out.start():]
    lines = chunk.split("\n")

    # lines[-3] is "Ran NN tests in 0.242s"
    # lines[-2] is blank
    # lines[-1] is 'OK' or 'FAILED (failures=1, errors=12)'
    #  or 'FAILED (failures=1)'
    #  or "PASSED (skips=N, successes=N)"
    # there might be other lines dumped here. Scan all the lines.

    for l in lines:
        if (l.startswith("OK") or
            l.startswith("FAILED ") or
            l.startswith("PASSED")):
            # the extra space on FAILED_ is to distinguish the overall
            # status from an individual test which failed. The lack of a
            # space on the OK is because it may be printed without any
            # additional text (if there are no skips,etc)
            out = re.search(r'failures=(\d+)', l)
            if out: res['failures'] = int(out.group(1))
            out = re.search(r'errors=(\d+)', l)
            if out: res['errors'] = int(out.group(1))
            out = re.search(r'skips=(\d+)', l)
            if out: res['skips'] = int(out.group(1))
            out = re.search(r'expectedFailures=(\d+)', l)
            if out: res['expectedFailures'] = int(out.group(1))
            out = re.search(r'unexpectedSuccesses=(\d+)', l)
            if out: res['unexpectedSuccesses'] = int(out.group(1))
            out = re.search(r'successes=(\d+)', l)
            if out: res['successes'] = int(out.group(1))

            return res

    return res