# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
r"""
Class describing simulation results
"""

import collections
import re

from Testplan import Result

_REGEX_REMOVE = [
    # Remove UVM time.
    re.compile(r'@\s+[\d.]+\s+[np]s: '),
    re.compile(r'\[[\d.]+\s+[np]s\] '),
    # Remove assertion time.
    re.compile(r'\(time [\d.]+ [PF]S\) '),
    # Remove leading spaces.
    re.compile(r'^\s+'),
    # Remove extra white spaces.
    re.compile(r'\s+(?=\s)'),
]

_REGEX_STRIP = [
    # Strip TB instance name.
    re.compile(r'[\w_]*top\.\S+\.(\w+)'),
    # Strip assertion.
    re.compile(r'(?<=Assertion )\S+\.(\w+)'),
]

# Regular expression for a separator: EOL or some of punctuation marks.
_SEPARATOR_RE = '($|[ ,.:;])'

_REGEX_STAR = [
    # Replace hex numbers with 0x (needs to be called before other numbers).
    re.compile(r'0x\s*[\da-fA-F]+'),
    # Replace hex numbers with 'h (needs to be called before other numbers).
    re.compile(r'\'h\s*[\da-fA-F]+'),
    # Floating point numbers at the beginning of a word, example "10.1ns".
    # (needs to be called before other numbers).
    re.compile(r'(?<=[^a-zA-Z0-9])\d+\.\d+'),
    # Replace all isolated numbers. Isolated numbers are numbers surrounded by
    # special symbols, for example ':' or '+' or '_', excluding parenthesis.
    # So a number with a letter or a round bracket on any one side, is
    # considered non-isolated number and is not starred by these expressions.
    re.compile(r'(?<=[^a-zA-Z0-9\(\)])\d+(?=($|[^a-zA-Z0-9\(\)]))'),
    # Replace numbers surrounded by parenthesis after a space and followed by a
    # separator.
    re.compile(r'(?<= \()\s*\d+\s*(?=\)%s)' % _SEPARATOR_RE),
    # Replace hex/decimal numbers after an equal sign or a semicolon and
    # followed by a separator. Uses look-behind pattern which need a
    # fixed width, thus the apparent redundancy.
    re.compile(r'(?<=[\w\]][=:])[\da-fA-F]+(?=%s)' % _SEPARATOR_RE),
    re.compile(r'(?<=[\w\]][=:] )[\da-fA-F]+(?=%s)' % _SEPARATOR_RE),
    re.compile(r'(?<=[\w\]] [=:])[\da-fA-F]+(?=%s)' % _SEPARATOR_RE),
    re.compile(r'(?<=[\w\]] [=:] )[\da-fA-F]+(?=%s)' % _SEPARATOR_RE),
    # Replace decimal number at the beginning of the word.
    re.compile(r'(?<= )\d+(?=\S)'),
    # Remove decimal number at end of the word and before '=' or '[' or
    # ',' or '.' or '('.
    re.compile(r'(?<=\S)\d+(?=($|[ =\[,\.\(]))'),
    # Replace the instance string.
    re.compile(r'(?<=instance)\s*=\s*\S+'),
]


class SimResults:
    '''An object wrapping up a table of results for some tests

    self.table is a list of Result objects, each of which
    corresponds to one or more runs of the test with a given name.

    self.buckets contains a dictionary accessed by the failure signature,
    holding all failing tests with the same signature.
    '''
    def __init__(self, items, results):
        self.table = []
        self.buckets = collections.defaultdict(list)
        self._name_to_row = {}
        for item in items:
            self._add_item(item, results)

    def _add_item(self, item, results):
        '''Recursively add a single item to the table of results'''
        status = results[item]
        if status == "F":
            bucket = self._bucketize(item.launcher.fail_msg.message)
            self.buckets[bucket].append(
                (item, item.launcher.fail_msg.line_number,
                 item.launcher.fail_msg.context))

        # Runs get added to the table directly
        if item.target == "run":
            self._add_run(item, status)

    def _add_run(self, item, status):
        '''Add an entry to table for item'''
        row = self._name_to_row.get(item.name)
        if row is None:
            row = Result(item.name)
            self.table.append(row)
            self._name_to_row[item.name] = row

        if status == 'P':
            row.passing += 1
        row.total += 1

    def _bucketize(self, fail_msg):
        bucket = fail_msg
        # Remove stuff.
        for regex in _REGEX_REMOVE:
            bucket = regex.sub('', bucket)
        # Strip stuff.
        for regex in _REGEX_STRIP:
            bucket = regex.sub(r'\g<1>', bucket)
        # Replace with '*'.
        for regex in _REGEX_STAR:
            bucket = regex.sub('*', bucket)
        return bucket
