import re
import sys

from ._elf import INSTRUCTIONS
from ._trace import TRACE, Trace

_pattern_ = re.compile(
    r"core\s+(\d+):\s*0x([0-9a-fA-F]+)\s*\(0x([0-9a-fA-F]+)\)"
)

def parse_spike_log(fname : str) -> None:
    """
    Parse spike log to generate linked list of Trace
    elements

    :param fname: Filename of trace to parse
    :type fname: str
    """
    prev = {}
    try:
        with open(fname) as f:
            for line in f:
                m = _pattern_.search(line)
                if m:
                    core, pc, _instr = m.groups()

                    core = int(core)
                    pc = int(pc, 16)

                    # Find instruction (based on pc)
                    instr = INSTRUCTIONS.get(pc, None)

                    if instr is None:
                        continue

                    # Create Trace (instructions in execution order)
                    trace = Trace(instr)

                    # Create the Linked list
                    if core not in TRACE:
                        TRACE[core] = trace

                    # Link
                    if core in prev and prev[core] is not None:
                        prev[core].link(trace)
                    prev[core] = trace

    except Exception as e:
        print(f"Failed to parse {fname} : {e}")
        sys.exit(1)

__all__ = [
    "parse_spike_log",
    ]
