# Copyright (c) 2013 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from . import parse
from . import colours
from .colours import unknownColour
from .point import Point
import re
from . import blobs
from time import time as wall_time
import os

id_parts = "TSPLFE"

all_ids = set(id_parts)
no_ids = set([])


class BlobDataSelect(object):
    """Represents which data is displayed for Ided object"""

    def __init__(self):
        # Copy all_ids
        self.ids = set(all_ids)

    def __and__(self, rhs):
        """And for filtering"""
        ret = BlobDataSelect()
        ret.ids = self.ids.intersection(rhs.ids)
        return ret


class BlobVisualData(object):
    """Super class for block data colouring"""

    def to_striped_block(self, select):
        """Return an array of colours to use for a striped block"""
        return unknownColour

    def get_inst(self):
        """Get an instruction Id (if any) from this data"""
        return None

    def get_line(self):
        """Get a line Id (if any) from this data"""
        return None

    def __repr__(self):
        return (
            self.__class__.__name__ + "().from_string(" + self.__str__() + ")"
        )

    def __str__(self):
        return ""


class Id(BlobVisualData):
    """A line or instruction id"""

    def __init__(self):
        self.isFault = False
        self.threadId = 0
        self.streamSeqNum = 0
        self.predictionSeqNum = 0
        self.lineSeqNum = 0
        self.fetchSeqNum = 0
        self.execSeqNum = 0

    def as_list(self):
        return [
            self.threadId,
            self.streamSeqNum,
            self.predictionSeqNum,
            self.lineSeqNum,
            self.fetchSeqNum,
            self.execSeqNum,
        ]

    def __cmp__(self, right):
        return cmp(self.as_list(), right.as_list())

    def from_string(self, string):
        m = re.match(
            "^(F;)?(\d+)/(\d+)\.(\d+)/(\d+)(/(\d+)(\.(\d+))?)?", string
        )

        def seqnum_from_string(string):
            if string is None:
                return 0
            else:
                return int(string)

        if m is None:
            print("Invalid Id string", string)
        else:
            elems = m.groups()

            if elems[0] is not None:
                self.isFault = True
            else:
                self.isFault = False

            self.threadId = seqnum_from_string(elems[1])
            self.streamSeqNum = seqnum_from_string(elems[2])
            self.predictionSeqNum = seqnum_from_string(elems[3])
            self.lineSeqNum = seqnum_from_string(elems[4])
            self.fetchSeqNum = seqnum_from_string(elems[6])
            self.execSeqNum = seqnum_from_string(elems[8])
        return self

    def get_inst(self):
        if self.fetchSeqNum != 0:
            return self
        else:
            return None

    def get_line(self):
        return self

    def __str__(self):
        """Returns the usual id T/S.P/L/F.E string"""
        return (
            str(self.threadId)
            + "/"
            + str(self.streamSeqNum)
            + "."
            + str(self.predictionSeqNum)
            + "/"
            + str(self.lineSeqNum)
            + "/"
            + str(self.fetchSeqNum)
            + "."
            + str(self.execSeqNum)
        )

    def to_striped_block(self, select):
        ret = []

        if self.isFault:
            ret.append(colours.faultColour)

        if "T" in select.ids:
            ret.append(colours.number_to_colour(self.threadId))
        if "S" in select.ids:
            ret.append(colours.number_to_colour(self.streamSeqNum))
        if "P" in select.ids:
            ret.append(colours.number_to_colour(self.predictionSeqNum))
        if "L" in select.ids:
            ret.append(colours.number_to_colour(self.lineSeqNum))
        if self.fetchSeqNum != 0 and "F" in select.ids:
            ret.append(colours.number_to_colour(self.fetchSeqNum))
        if self.execSeqNum != 0 and "E" in select.ids:
            ret.append(colours.number_to_colour(self.execSeqNum))

        if len(ret) == 0:
            ret = [colours.unknownColour]

        if self.isFault:
            ret.append(colours.faultColour)

        return ret


class Branch(BlobVisualData):
    """Branch data new stream and prediction sequence numbers, a branch
    reason and a new PC"""

    def __init__(self):
        self.newStreamSeqNum = 0
        self.newPredictionSeqNum = 0
        self.newPC = 0
        self.reason = "NoBranch"
        self.id = Id()

    def from_string(self, string):
        m = re.match("^(\w+);(\d+)\.(\d+);([0-9a-fA-Fx]+);(.*)$", string)

        if m is not None:
            (
                self.reason,
                newStreamSeqNum,
                newPredictionSeqNum,
                newPC,
                id,
            ) = m.groups()

            self.newStreamSeqNum = int(newStreamSeqNum)
            self.newPredictionSeqNum = int(newPredictionSeqNum)
            self.newPC = int(newPC, 0)
            self.id = special_view_decoder(Id)(id)
            # self.branch = special_view_decoder(Branch)(branch)
        else:
            print("Bad Branch data:", string)
        return self

    def to_striped_block(self, select):
        return [
            colours.number_to_colour(self.newStreamSeqNum),
            colours.number_to_colour(self.newPredictionSeqNum),
            colours.number_to_colour(self.newPC),
        ]


class Counts(BlobVisualData):
    """Treat the input data as just a /-separated list of count values (or
    just a single value)"""

    def __init__(self):
        self.counts = []

    def from_string(self, string):
        self.counts = list(map(int, re.split("/", string)))
        return self

    def to_striped_block(self, select):
        return list(map(colours.number_to_colour, self.counts))


class Colour(BlobVisualData):
    """A fixed colour block, used for special colour decoding"""

    def __init__(self, colour):
        self.colour = colour

    def to_striped_block(self, select):
        return [self.colour]


class DcacheAccess(BlobVisualData):
    """Data cache accesses [RW];id"""

    def __init__(self):
        self.direc = "R"
        self.id = Id()

    def from_string(self, string):
        self.direc, id = re.match("^([RW]);([^;]*);.*$", string).groups()
        self.id.from_string(id)
        return self

    def get_inst(self):
        return self.id

    def to_striped_block(self, select):
        if self.direc == "R":
            direc_colour = colours.readColour
        elif self.direc == "R":
            direc_colour = colours.writeColour
        else:
            direc_colour = colours.errorColour
        return [direc_colour] + self.id.to_striped_block(select)


class ColourPattern(object):
    """Super class for decoders that make 2D grids rather than just single
    striped blocks"""

    def elems(self):
        return []

    def to_striped_block(self, select):
        return [[[colours.errorColour]]]


def special_view_decoder(class_):
    """Generate a decode function that checks for special character
    arguments first (and generates a fixed colour) before building a
    BlobVisualData of the given class"""

    def decode(symbol):
        if symbol in special_state_colours:
            return Colour(special_state_colours[symbol])
        else:
            return class_().from_string(symbol)

    return decode


class TwoDColours(ColourPattern):
    """A 2D grid pattern decoder"""

    def __init__(self, blockss):
        self.blockss = blockss

    @classmethod
    def decoder(class_, elemClass, dataName):
        """Factory for making decoders for particular block types"""

        def decode(pairs):
            if dataName not in pairs:
                print(
                    "TwoDColours: no event data called:",
                    dataName,
                    "in:",
                    pairs,
                )
                return class_([[Colour(colours.errorColour)]])
            else:
                parsed = parse.list_parser(pairs[dataName])
                return class_(
                    parse.map2(special_view_decoder(elemClass), parsed)
                )

        return decode

    @classmethod
    def indexed_decoder(class_, elemClass, dataName, picPairs):
        """Factory for making decoders for particular block types but
        where the list elements are pairs of (index, data) and
        strip and stripelems counts are picked up from the pair
        data on the decoder's picture file.  This gives a 2D layout
        of the values with index 0 at strip=0, elem=0 and index 1
        at strip=0, elem=1"""

        def decode(pairs):
            if dataName not in pairs:
                print(
                    "TwoDColours: no event data called:",
                    dataName,
                    "in:",
                    pairs,
                )
                return class_([[Colour(colours.errorColour)]])
            else:
                strips = int(picPairs["strips"])
                strip_elems = int(picPairs["stripelems"])

                raw_iv_pairs = pairs[dataName]

                parsed = parse.parse_indexed_list(raw_iv_pairs)

                array = [
                    [
                        Colour(colours.emptySlotColour)
                        for i in range(0, strip_elems)
                    ]
                    for j in range(0, strips)
                ]

                for index, value in parsed:
                    try:
                        array[index % strips][
                            index / strips
                        ] = special_view_decoder(elemClass)(value)
                    except:
                        print(
                            "Element out of range strips: %d,"
                            " stripelems %d, index: %d"
                            % (strips, strip_elems, index)
                        )

                # return class_(array)
                return class_(array)

        return decode

    def elems(self):
        """Get a flat list of all elements"""
        ret = []
        for blocks in self.blockss:
            ret += blocks
        return ret

    def to_striped_block(self, select):
        return parse.map2(lambda d: d.to_striped_block(select), self.blockss)


class FrameColours(ColourPattern):
    """Decode to a 2D grid which has a single occupied row from the event
    data and some blank rows forming a frame with the occupied row as a
    'title' coloured stripe"""

    def __init__(self, block, numBlankSlots):
        self.numBlankSlots = numBlankSlots
        self.block = block

    @classmethod
    def decoder(class_, elemClass, numBlankSlots, dataName):
        """Factory for element type"""

        def decode(pairs):
            if dataName not in pairs:
                print(
                    "FrameColours: no event data called:",
                    dataName,
                    "in:",
                    pairs,
                )
                return class_([Colour(colours.errorColour)])
            else:
                parsed = parse.list_parser(pairs[dataName])
                return class_(
                    special_view_decoder(elemClass)(parsed[0][0]),
                    numBlankSlots,
                )

        return decode

    def elems(self):
        return [self.block]

    def to_striped_block(self, select):
        return [[self.block.to_striped_block(select)]] + (
            self.numBlankSlots * [[[colours.backgroundColour]]]
        )


special_state_colours = {
    "U": colours.unknownColour,
    "B": colours.blockedColour,
    "-": colours.bubbleColour,
    "": colours.emptySlotColour,
    "E": colours.emptySlotColour,
    "R": colours.reservedSlotColour,
    "X": colours.errorColour,
    "F": colours.faultColour,
    "r": colours.readColour,
    "w": colours.writeColour,
}

special_state_names = {
    "U": "(U)nknown",
    "B": "(B)locked",
    "-": "(-)Bubble",
    "": "()Empty",
    "E": "(E)mpty",
    "R": "(R)eserved",
    "X": "(X)Error",
    "F": "(F)ault",
    "r": "(r)ead",
    "w": "(w)rite",
}

special_state_chars = list(special_state_colours.keys())

# The complete set of available block data types
decoder_element_classes = {
    "insts": Id,
    "lines": Id,
    "branch": Branch,
    "dcache": DcacheAccess,
    "counts": Counts,
}

indexed_decoder_element_classes = {"indexedCounts": Counts}


def find_colour_decoder(stripSpace, decoderName, dataName, picPairs):
    """Make a colour decoder from some picture file blob attributes"""
    if decoderName == "frame":
        return FrameColours.decoder(Counts, stripSpace, dataName)
    elif decoderName in decoder_element_classes:
        return TwoDColours.decoder(
            decoder_element_classes[decoderName], dataName
        )
    elif decoderName in indexed_decoder_element_classes:
        return TwoDColours.indexed_decoder(
            indexed_decoder_element_classes[decoderName], dataName, picPairs
        )
    else:
        return None


class IdedObj(object):
    """An object identified by an Id carrying paired data.
    The super class for Inst and Line"""

    def __init__(self, id, pairs={}):
        self.id = id
        self.pairs = pairs

    def __cmp__(self, right):
        return cmp(self.id, right.id)

    def table_line(self):
        """Represent the object as a list of table row data"""
        return []

    # FIXME, add a table column titles?

    def __repr__(self):
        return " ".join(self.table_line())


class Inst(IdedObj):
    """A non-fault instruction"""

    def __init__(self, id, disassembly, addr, pairs={}):
        super(Inst, self).__init__(id, pairs)
        if "nextAddr" in pairs:
            self.nextAddr = int(pairs["nextAddr"], 0)
            del pairs["nextAddr"]
        else:
            self.nextAddr = None
        self.disassembly = disassembly
        self.addr = addr

    def table_line(self):
        if self.nextAddr is not None:
            addrStr = f"0x{self.addr:x}->0x{self.nextAddr:x}"
        else:
            addrStr = f"0x{self.addr:x}"
        ret = [addrStr, self.disassembly]
        for name, value in self.pairs.items():
            ret.append(f"{name}={str(value)}")
        return ret


class InstFault(IdedObj):
    """A fault instruction"""

    def __init__(self, id, fault, addr, pairs={}):
        super(InstFault, self).__init__(id, pairs)
        self.fault = fault
        self.addr = addr

    def table_line(self):
        ret = [f"0x{self.addr:x}", self.fault]
        for name, value in self.pairs:
            ret.append("%s=%s", name, str(value))
        return ret


class Line(IdedObj):
    """A fetched line"""

    def __init__(self, id, vaddr, paddr, size, pairs={}):
        super(Line, self).__init__(id, pairs)
        self.vaddr = vaddr
        self.paddr = paddr
        self.size = size

    def table_line(self):
        ret = [f"0x{self.vaddr:x}/0x{self.paddr:x}", "%d" % self.size]
        for name, value in self.pairs:
            ret.append("%s=%s", name, str(value))
        return ret


class LineFault(IdedObj):
    """A faulting line"""

    def __init__(self, id, fault, vaddr, pairs={}):
        super(LineFault, self).__init__(id, pairs)
        self.vaddr = vaddr
        self.fault = fault

    def table_line(self):
        ret = [f"0x{self.vaddr:x}", self.fault]
        for name, value in self.pairs:
            ret.append("%s=%s", name, str(value))
        return ret


class BlobEvent(object):
    """Time event for a single blob"""

    def __init__(self, unit, time, pairs={}):
        # blob's unit name
        self.unit = unit
        self.time = time
        # dict of picChar (blob name) to visual data
        self.visuals = {}
        # Miscellaneous unparsed MinorTrace line data
        self.pairs = pairs
        # Non-MinorTrace debug printout for this unit at this time
        self.comments = []

    def find_ided_objects(self, model, picChar, includeInstLines):
        """Find instructions/lines mentioned in the blob's event
        data"""
        ret = []
        if picChar in self.visuals:
            blocks = self.visuals[picChar].elems()

            def find_inst(data):
                instId = data.get_inst()
                lineId = data.get_line()
                if instId is not None:
                    inst = model.find_inst(instId)
                    line = model.find_line(instId)
                    if inst is not None:
                        ret.append(inst)
                    if includeInstLines and line is not None:
                        ret.append(line)
                elif lineId is not None:
                    line = model.find_line(lineId)
                    if line is not None:
                        ret.append(line)

            list(map(find_inst, blocks))
        return sorted(ret)


class BlobModel(object):
    """Model bringing together blob definitions and parsed events"""

    def __init__(self, unitNamePrefix=""):
        self.blobs = []
        self.unitNameToBlobs = {}
        self.unitEvents = {}
        self.clear_events()
        self.picSize = Point(20, 10)
        self.lastTime = 0
        self.unitNamePrefix = unitNamePrefix

    def clear_events(self):
        """Drop all events and times"""
        self.lastTime = 0
        self.times = []
        self.insts = {}
        self.lines = {}
        self.numEvents = 0

        for unit, events in self.unitEvents.items():
            self.unitEvents[unit] = []

    def add_blob(self, blob):
        """Add a parsed blob to the model"""
        self.blobs.append(blob)
        if blob.unit not in self.unitNameToBlobs:
            self.unitNameToBlobs[blob.unit] = []

        self.unitNameToBlobs[blob.unit].append(blob)

    def add_inst(self, inst):
        """Add a MinorInst instruction definition to the model"""
        # Is this a non micro-op instruction.  Microops (usually) get their
        #   fetchSeqNum == 0 varient stored first
        macroop_key = (inst.id.fetchSeqNum, 0)
        full_key = (inst.id.fetchSeqNum, inst.id.execSeqNum)

        if inst.id.execSeqNum != 0 and macroop_key not in self.insts:
            self.insts[macroop_key] = inst

        self.insts[full_key] = inst

    def find_inst(self, id):
        """Find an instruction either as a microop or macroop"""
        macroop_key = (id.fetchSeqNum, 0)
        full_key = (id.fetchSeqNum, id.execSeqNum)

        if full_key in self.insts:
            return self.insts[full_key]
        elif macroop_key in self.insts:
            return self.insts[macroop_key]
        else:
            return None

    def add_line(self, line):
        """Add a MinorLine line to the model"""
        self.lines[line.id.lineSeqNum] = line

    def add_unit_event(self, event):
        """Add a single event to the model.  This must be an event at a
        time >= the current maximum time"""
        if event.unit in self.unitEvents:
            events = self.unitEvents[event.unit]
            if len(events) > 0 and events[len(events) - 1].time > event.time:
                print("Bad event ordering")
            events.append(event)
        self.numEvents += 1
        self.lastTime = max(self.lastTime, event.time)

    def extract_times(self):
        """Extract a list of all the times from the seen events.  Call after
        reading events to give a safe index list to use for time indices"""
        times = {}
        for unitEvents in self.unitEvents.values():
            for event in unitEvents:
                times[event.time] = 1
        self.times = list(times.keys())
        self.times.sort()

    def find_line(self, id):
        """Find a line by id"""
        key = id.lineSeqNum
        return self.lines.get(key, None)

    def find_event_bisection(
        self, unit, time, events, lower_index, upper_index
    ):
        """Find an event by binary search on time indices"""
        while lower_index <= upper_index:
            pivot = (upper_index + lower_index) / 2
            pivotEvent = events[pivot]
            event_equal = pivotEvent.time == time or (
                pivotEvent.time < time
                and (pivot == len(events) - 1 or events[pivot + 1].time > time)
            )

            if event_equal:
                return pivotEvent
            elif time > pivotEvent.time:
                if pivot == upper_index:
                    return None
                else:
                    lower_index = pivot + 1
            elif time < pivotEvent.time:
                if pivot == lower_index:
                    return None
                else:
                    upper_index = pivot - 1
            else:
                return None
        return None

    def find_unit_event_by_time(self, unit, time):
        """Find the last event for the given unit at time <= time"""
        if unit in self.unitEvents:
            events = self.unitEvents[unit]
            ret = self.find_event_bisection(
                unit, time, events, 0, len(events) - 1
            )

            return ret
        else:
            return None

    def find_time_index(self, time):
        """Find a time index close to the given time (where
        times[return] <= time and times[return+1] > time"""
        ret = 0
        lastIndex = len(self.times) - 1
        while ret < lastIndex and self.times[ret + 1] <= time:
            ret += 1
        return ret

    def add_minor_inst(self, rest):
        """Parse and add a MinorInst line to the model"""
        pairs = parse.parse_pairs(rest)
        other_pairs = dict(pairs)

        id = Id().from_string(pairs["id"])
        del other_pairs["id"]

        addr = int(pairs["addr"], 0)
        del other_pairs["addr"]

        if "inst" in other_pairs:
            del other_pairs["inst"]

            # Collapse unnecessary spaces in disassembly
            disassembly = re.sub("  *", " ", re.sub("^ *", "", pairs["inst"]))

            inst = Inst(id, disassembly, addr, other_pairs)
            self.add_inst(inst)
        elif "fault" in other_pairs:
            del other_pairs["fault"]

            inst = InstFault(id, pairs["fault"], addr, other_pairs)

            self.add_inst(inst)

    def add_minor_line(self, rest):
        """Parse and add a MinorLine line to the model"""
        pairs = parse.parse_pairs(rest)
        other_pairs = dict(pairs)

        id = Id().from_string(pairs["id"])
        del other_pairs["id"]

        vaddr = int(pairs["vaddr"], 0)
        del other_pairs["vaddr"]

        if "paddr" in other_pairs:
            del other_pairs["paddr"]
            del other_pairs["size"]
            paddr = int(pairs["paddr"], 0)
            size = int(pairs["size"], 0)

            self.add_line(Line(id, vaddr, paddr, size, other_pairs))
        elif "fault" in other_pairs:
            del other_pairs["fault"]

            self.add_line(LineFault(id, pairs["fault"], vaddr, other_pairs))

    def load_events(self, file, startTime=0, endTime=None):
        """Load an event file and add everything to this model"""

        def update_comments(comments, time):
            # Add a list of comments to an existing event, if there is one at
            #   the given time, or create a new, correctly-timed, event from
            #   the last event and attach the comments to that
            for commentUnit, commentRest in comments:
                event = self.find_unit_event_by_time(commentUnit, time)
                # Find an event to which this comment can be attached
                if event is None:
                    # No older event, make a new empty one
                    event = BlobEvent(commentUnit, time, {})
                    self.add_unit_event(event)
                elif event.time != time:
                    # Copy the old event and make a new one with the right
                    #   time and comment
                    newEvent = BlobEvent(commentUnit, time, event.pairs)
                    newEvent.visuals = dict(event.visuals)
                    event = newEvent
                    self.add_unit_event(event)
                event.comments.append(commentRest)

        self.clear_events()

        # A negative time will *always* be different from an event time
        time = -1
        time_events = {}
        last_time_lines = {}
        minor_trace_line_count = 0
        comments = []

        default_colour = [[colours.unknownColour]]
        next_progress_print_event_count = 1000

        if not os.access(file, os.R_OK):
            print("Can't open file", file)
            exit(1)
        else:
            print("Opening file", file)

        f = open(file)

        start_wall_time = wall_time()

        # Skip leading events
        still_skipping = True
        l = f.readline()
        while l and still_skipping:
            match = re.match("^\s*(\d+):", l)
            if match is not None:
                event_time = match.groups()
                if int(event_time[0]) >= startTime:
                    still_skipping = False
                else:
                    l = f.readline()
            else:
                l = f.readline()

        match_line_re = re.compile(
            "^\s*(\d+):\s*([\w\.]+):\s*(Minor\w+:)?\s*(.*)$"
        )

        # Parse each line of the events file, accumulating comments to be
        #   attached to MinorTrace events when the time changes
        reached_end_time = False
        while not reached_end_time and l:
            match = match_line_re.match(l)
            if match is not None:
                event_time, unit, line_type, rest = match.groups()
                event_time = int(event_time)

                unit = re.sub(
                    "^" + self.unitNamePrefix + "\.?(.*)$", "\\1", unit
                )

                # When the time changes, resolve comments
                if event_time != time:
                    if self.numEvents > next_progress_print_event_count:
                        print(("Parsed to time: %d" % event_time))
                        next_progress_print_event_count = self.numEvents + 1000
                    update_comments(comments, time)
                    comments = []
                    time = event_time

                if line_type is None:
                    # Treat this line as just a 'comment'
                    comments.append((unit, rest))
                elif line_type == "MinorTrace:":
                    minor_trace_line_count += 1

                    # Only insert this event if it's not the same as
                    #   the last event we saw for this unit
                    if last_time_lines.get(unit, None) != rest:
                        event = BlobEvent(unit, event_time, {})
                        pairs = parse.parse_pairs(rest)
                        event.pairs = pairs

                        # Try to decode the colour data for this event
                        blobs = self.unitNameToBlobs.get(unit, [])
                        for blob in blobs:
                            if blob.visualDecoder is not None:
                                event.visuals[
                                    blob.picChar
                                ] = blob.visualDecoder(pairs)

                        self.add_unit_event(event)
                        last_time_lines[unit] = rest
                elif line_type == "MinorInst:":
                    self.add_minor_inst(rest)
                elif line_type == "MinorLine:":
                    self.add_minor_line(rest)

            if endTime is not None and time > endTime:
                reached_end_time = True

            l = f.readline()

        update_comments(comments, time)
        self.extract_times()
        f.close()

        end_wall_time = wall_time()

        print(
            "Total events:",
            minor_trace_line_count,
            "unique events:",
            self.numEvents,
        )
        print("Time to parse:", end_wall_time - start_wall_time)

    def add_blob_picture(self, offset, pic, nameDict):
        """Add a parsed ASCII-art pipeline markup to the model"""
        pic_width = 0
        for line in pic:
            pic_width = max(pic_width, len(line))
        pic_height = len(pic)

        # Number of horizontal characters per 'pixel'.  Should be 2
        charsPerPixel = 2

        # Clean up pic_width to a multiple of charsPerPixel
        pic_width = (pic_width + charsPerPixel - 1) // 2

        self.picSize = Point(pic_width, pic_height)

        def pic_at(point):
            """Return the char pair at the given point.
            Returns None for characters off the picture"""
            x, y = point.to_pair()
            x *= 2
            if y >= len(pic) or x >= len(pic[y]):
                return None
            else:
                return pic[y][x : x + charsPerPixel]

        def clear_pic_at(point):
            """Clear the chars at point so we don't trip over them again"""
            line = pic[point.y]
            x = point.x * charsPerPixel
            pic[point.y] = (
                line[0:x] + (" " * charsPerPixel) + line[x + charsPerPixel :]
            )

        def skip_same_char(start, increment):
            """Skip characters which match pic_at(start)"""
            char = pic_at(start)
            hunt = start
            while pic_at(hunt) == char:
                hunt += increment
            return hunt

        def find_size(start):
            """Find the size of a rectangle with top left hand corner at
            start consisting of (at least) a -. shaped corner describing
            the top right corner of a rectangle of the same char"""
            char = pic_at(start)
            hunt_x = skip_same_char(start, Point(1, 0))
            hunt_y = skip_same_char(start, Point(0, 1))
            off_bottom_right = (hunt_x * Point(1, 0)) + (hunt_y * Point(0, 1))
            return off_bottom_right - start

        def point_return(point):
            """Carriage return, line feed"""
            return Point(0, point.y + 1)

        def find_arrow(start):
            """Find a simple 1-char wide arrow"""

            def body(endChar, contChar, direc):
                arrow_point = start
                arrow_point += Point(0, 1)
                clear_pic_at(start)
                while pic_at(arrow_point) == contChar:
                    clear_pic_at(arrow_point)
                    arrow_point += Point(0, 1)

                if pic_at(arrow_point) == endChar:
                    clear_pic_at(arrow_point)
                    self.add_blob(
                        blobs.Arrow(
                            "_",
                            start + offset,
                            direc=direc,
                            size=(Point(1, 1) + arrow_point - start),
                        )
                    )
                else:
                    print("Bad arrow", start)

            char = pic_at(start)
            if char == "-\\":
                body("-/", " :", "right")
            elif char == "/-":
                body("\\-", ": ", "left")

        blank_chars = ["  ", " :", ": "]

        # Traverse the picture left to right, top to bottom to find blobs
        seen_dict = {}
        point = Point(0, 0)
        while pic_at(point) is not None:
            while pic_at(point) is not None:
                char = pic_at(point)
                if char == "->":
                    self.add_blob(
                        blobs.Arrow("_", point + offset, direc="right")
                    )
                elif char == "<-":
                    self.add_blob(
                        blobs.Arrow("_", point + offset, direc="left")
                    )
                elif char == "-\\" or char == "/-":
                    find_arrow(point)
                elif char in blank_chars:
                    pass
                else:
                    if char not in seen_dict:
                        size = find_size(point)
                        topLeft = point + offset
                        if char not in nameDict:
                            # Unnamed blobs
                            self.add_blob(
                                blobs.Block(
                                    char,
                                    nameDict.get(char, "_"),
                                    topLeft,
                                    size=size,
                                )
                            )
                        else:
                            # Named blobs, set visual info.
                            blob = nameDict[char]
                            blob.size = size
                            blob.topLeft = topLeft
                            self.add_blob(blob)
                    seen_dict[char] = True
                point = skip_same_char(point, Point(1, 0))
            point = point_return(point)

    def load_picture(self, filename):
        """Load a picture file into the model"""

        def parse_blob_description(char, unit, macros, pairsList):
            # Parse the name value pairs in a blob-describing line
            def expand_macros(pairs, newPairs):
                # Recursively expand macros
                for name, value in newPairs:
                    if name in macros:
                        expand_macros(pairs, macros[name])
                    else:
                        pairs[name] = value
                return pairs

            pairs = expand_macros({}, pairsList)

            ret = None

            typ = pairs.get("type", "block")
            colour = colours.name_to_colour(pairs.get("colour", "black"))

            if typ == "key":
                ret = blobs.Key(char, unit, Point(0, 0), colour)
            elif typ == "block":
                ret = blobs.Block(char, unit, Point(0, 0), colour)
            else:
                print("Bad picture blog type:", typ)

            if "hideId" in pairs:
                hide = pairs["hideId"]
                ret.dataSelect.ids -= set(hide)

            if typ == "block":
                ret.displayName = pairs.get("name", unit)
                ret.nameLoc = pairs.get("nameLoc", "top")
                ret.shape = pairs.get("shape", "box")
                ret.stripDir = pairs.get("stripDir", "horiz")
                ret.stripOrd = pairs.get("stripOrd", "LR")
                ret.blankStrips = int(pairs.get("blankStrips", "0"))
                ret.shorten = int(pairs.get("shorten", "0"))

                if "decoder" in pairs:
                    decoderName = pairs["decoder"]
                    dataElement = pairs.get("dataElement", decoderName)

                    decoder = find_colour_decoder(
                        ret.blankStrips, decoderName, dataElement, pairs
                    )
                    if decoder is not None:
                        ret.visualDecoder = decoder
                    else:
                        print("Bad visualDecoder requested:", decoderName)

                if "border" in pairs:
                    border = pairs["border"]
                    if border == "thin":
                        ret.border = 0.2
                    elif border == "mid":
                        ret.border = 0.5
                    else:
                        ret.border = 1.0
            elif typ == "key":
                ret.colours = pairs.get("colours", ret.colours)

            return ret

        def line_is_comment(line):
            """Returns true if a line starts with #, returns False
            for lines which are None"""
            return line is not None and re.match("^\s*#", line) is not None

        def get_line(f):
            """Get a line from file f extending that line if it ends in
            '\' and dropping lines that start with '#'s"""
            ret = f.readline()

            # Discard comment lines
            while line_is_comment(ret):
                ret = f.readline()

            if ret is not None:
                extend_match = re.match("^(.*)\\\\$", ret)

                while extend_match is not None:
                    new_line = f.readline()

                    if new_line is not None and not line_is_comment(new_line):
                        (line_wo_backslash,) = extend_match.groups()
                        ret = line_wo_backslash + new_line
                        extend_match = re.match("^(.*)\\\\$", ret)
                    else:
                        extend_match = None

            return ret

        # Macros are recursively expanded into name=value pairs
        macros = {}

        if not os.access(filename, os.R_OK):
            print("Can't open file", filename)
            exit(1)
        else:
            print("Opening file", filename)

        f = open(filename)
        l = get_line(f)
        picture = []
        blob_char_dict = {}

        self.unitEvents = {}
        self.clear_events()

        # Actually parse the file
        in_picture = False
        while l:
            l = parse.remove_trailing_ws(l)
            l = re.sub("#.*", "", l)

            if re.match("^\s*$", l) is not None:
                pass
            elif l == "<<<":
                in_picture = True
            elif l == ">>>":
                in_picture = False
            elif in_picture:
                picture.append(re.sub("\s*$", "", l))
            else:
                line_match = re.match(
                    "^([a-zA-Z0-9][a-zA-Z0-9]):\s+([\w.]+)\s*(.*)", l
                )
                macro_match = re.match("macro\s+(\w+):(.*)", l)

                if macro_match is not None:
                    name, defn = macro_match.groups()
                    macros[name] = parse.parse_pairs_list(defn)
                elif line_match is not None:
                    char, unit, pairs = line_match.groups()
                    blob = parse_blob_description(
                        char, unit, macros, parse.parse_pairs_list(pairs)
                    )
                    blob_char_dict[char] = blob
                    # Setup the events structure
                    self.unitEvents[unit] = []
                else:
                    print("Problem with Blob line:", l)

            l = get_line(f)

        self.blobs = []
        self.add_blob_picture(Point(0, 1), picture, blob_char_dict)
