# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
#
# Convert I2C master format to SVG

import logging as log
from collections import namedtuple

import i2csvg.i2csvg_data as sdata


# validating version of int(x, 0)
# returns int value, error flag
# if error flag is True value will be zero
def check_int(x, err_prefix):
    if isinstance(x, int):
        return x, False
    if len(x) == 0:
        log.error(err_prefix + " Zero length string")
        return 0, True
    if x[0] == '0' and len(x) > 2:
        if x[1] in 'bB':
            validch = '01'
        elif x[1] in 'oO':
            validch = '01234567'
        elif x[1] in 'xX':
            validch = '0123456789abcdefABCDEF'
        else:
            log.error(err_prefix +
                      ": int must start digit, 0b, 0B, 0o, 0O, 0x or 0X")
            return 0, True
        for c in x[2:]:
            if not c in validch:
                log.error(err_prefix + ": Bad character " + c + " in " + x)
                return 0, True
    else:
        if not x.isdecimal():
            log.error(err_prefix + ": Number not valid int " + x)
            return 0, 1
    return int(x, 0), False


def check_single(line, char, fullline, err):
    ''' Check for character char in input line
        Return True if there is one (or more)
        Propagate err or force to err True if more than one char
    '''
    res = False
    if char in line:
        res = True
        if line.count(char) > 1:
            log.warning('Multiple ' + char + ' in line ' + fullline)
            err = True
    return res, err


I2cOp = namedtuple('I2cOp',
                   'read rcont start stop nackok mvalue adr size fbyte tag')


def check_and_size(iic, line):
    ''' Check I2C Op for validity and return size in bits
    '''
    err = False
    if iic.start and iic.read:
        log.error('Start and Read found in ' + line)
        err = True
    if iic.rcont and not iic.read:
        log.error('RCont without Read found in ' + line)
        err = True

    # documentation says R+C and P is not permitted, but I think it
    # is needed for protocols where the last read data is ACKed?
    # (these don't match I2C or SMBus spec but exist in the wild)

    size = 0
    if iic.start:
        size += 1
    if iic.stop:
        size += 1
    if iic.read:
        # multi is D0, D1, ..., Dn-1 so 3 byte/acks and a 1 bit squiggle
        # regular read is one byte/ack per
        size += 9 * 3 + 1 if iic.mvalue else 9 * iic.fbyte
    else:
        # write data is one byte/ack
        size += 9
    # rcont, nackok just affect the polarity of the final ack bit
    # adr just affects how the write data is drawn
    return size, err


def parse_i2c_fifodata(line):
    ''' Parse input line of I2C FDATA fifo and convert to internal type
        Line is usually 0x + the hex value written to the register
        But could be binary (0b), octal (0o) or decimal
    '''
    fifodata, err = check_int(line, 'FIFO value')
    # bit values here must match the register definition!
    ress = (fifodata & 0x0100) != 0
    resp = (fifodata & 0x0200) != 0
    resr = (fifodata & 0x0400) != 0
    resc = (fifodata & 0x0800) != 0
    resn = (fifodata & 0x1000) != 0
    resb = fifodata & 0xff
    resm = False  # only used in descriptive case
    resa = False  # only used in descriptive case

    tmpr = I2cOp(resr, resc, ress, resp, resn, resm, resa, 0, resb, None)
    size, serr = check_and_size(tmpr, line)
    if serr:
        err = True
    return I2cOp(resr, resc, ress, resp, resn, resm, resa, size, resb,
                 None), err


def parse_i2c_code(line):
    ''' Parse input line of I2C FDATA fifo and convert to internal type
        Line is coded with flags and an 8-bit data value
        S - Start flag, P - stop flag,
        R - read flag, C - continue read flag, N - NackOk flag
        followed by the data byte
        Special cases: 
        M - indicates multiple bytes instead of data byte
        A - followed by 0 or 1 address/direction or 2 address/data
        Data value in quotes is a tag
    '''
    resr, resc, ress, resp, resn = False, False, False, False, False
    resm, resa, resb = False, False, 0

    err = False
    firstval = 0
    for i in line:
        if i.isdigit() or i == "'":
            break
        firstval += 1
    # Will only check the flags section, so no concern about hex digits
    ress, err = check_single(line[:firstval], 'S', line, err)
    resp, err = check_single(line[:firstval], 'P', line, err)
    resr, err = check_single(line[:firstval], 'R', line, err)
    resc, err = check_single(line[:firstval], 'C', line, err)
    resn, err = check_single(line[:firstval], 'N', line, err)
    # these two are formally part of the value but parse like flags
    resm, err = check_single(line[:firstval], 'M', line, err)
    resa, err = check_single(line[:firstval], 'A', line, err)

    if firstval == len(line):
        if not resm:
            err = True
            log.error('No value found in ' + line)
        rest = None
    else:
        if resm:
            err = True
            log.error('Found M and value in ' + line)
            rest = None
            resb = 0
        elif line[firstval] == "'":
            rest = line[firstval + 1:-1]
            resb = 0
        else:
            rest = None
            resb, verr = check_int(line[firstval:],
                                   'Value in ' + line + ' ' + str(firstval))
            if verr:
                err = True
    if resb < 0 or resb > 255 or (resa and resb > 2):
        log.error('Value out of range in ' + line)
        resb = 0
        err = True

    tmpr = I2cOp(resr, resc, ress, resp, resn, resm, resa, 0, resb, rest)
    size, serr = check_and_size(tmpr, line)
    if serr:
        err = True
    return I2cOp(resr, resc, ress, resp, resn, resm, resa, size, resb,
                 rest), err


def parse_file(infile, fifodata=False, prefix=None):
    ''' Parse a file of I2C data
        fifodata indicates if the data is a dump from writes to FDATA fifo
        prefix is a prefix on valid lines and will be stripped
               lines without the prefix are ignored
        Returns list of I2cOps or str (for titles)
    '''
    transaction = []
    errors = 0
    firstline = True

    for line in infile:
        if prefix:
            if not line.startswith(prefix):
                continue
            line = line[len(prefix):]

        if len(line) == 0 or line.isspace() or line[0] == '#':
            continue
        line = line.lstrip().rstrip()
        if line[0] == 'T':
            transaction.append(line[1:].lstrip())
            continue
        schar = ','
        if fifodata and not ',' in line:
            # fifodata could also be whitespace spearated
            schar = None

        for sline in line.split(sep=schar):
            if fifodata:
                t, err = parse_i2c_fifodata(sline)
            else:
                t, err = parse_i2c_code(sline)
            if err:
                errors += 1
            else:
                transaction.append(t)
    if errors > 0:
        log.error('Found ' + str(errors) + ' errors in input')
    return transaction


def output_debug(outfile, t, term):
    for tr in t:
        outfile.write(str(tr) + term)


def text_element(tr, term, titles):
    if isinstance(tr, str):
        if titles:
            return 'T ' + tr + term
        return ''
    flags = 'S' if tr.start else '.'
    flags += 'P' if tr.stop else '.'
    flags += 'R' if tr.read else '.'
    flags += 'C' if tr.rcont else '.'
    flags += 'N' if tr.nackok else '.'

    # mvalue and adr are only for drawing, but can propagate in value
    if tr.adr:
        val = 'A' + str(tr.fbyte)
    else:
        if tr.tag:
            val = "'" + tr.tag + "'"
        else:
            val = 'M' if tr.mvalue else hex(tr.fbyte)
    return flags + ' ' + val + term


def output_text(outfile, transactions, term, titles=True):
    for tr in transactions:
        text = text_element(tr, term, titles)
        if text:
            outfile.write(text)


# use will place a defined group at the given x,y
def svg_use(item, x, y):
    return '    <use href="#' + item + '" x="' + str(x) + \
        '" y="' + str(y) + '" />\n'


# a byte write is a byte of data from the host and an ack from the device
def svg_wrbyte(xpos, ypos, nok, label):
    rtext = svg_use('hbyte', xpos, ypos)
    rtext += '    <text x="' + str(xpos + (sdata.bytew / 2))
    rtext += '" y="' + str(ypos + sdata.txty) + '">\n'
    rtext += label
    rtext += '</text>\n'
    xpos += sdata.bytew
    if nok:
        rtext += svg_use('norackd', xpos, ypos)
    else:
        rtext += svg_use('ackd', xpos, ypos)
    xpos += sdata.bitw
    return rtext, xpos


# a byte read is a byte of data from the device and an ack/nack from the host
def svg_rdbyte(xpos, ypos, ack, label):
    rtext = svg_use('dbyte', xpos, ypos)
    rtext += '    <text x="' + str(xpos + (sdata.bytew / 2))
    rtext += '" y="' + str(ypos + sdata.txty) + '">\n'
    rtext += label
    rtext += '</text>\n'
    xpos += sdata.bytew
    rtext += svg_use(ack, xpos, ypos)
    xpos += sdata.bitw
    return rtext, xpos


def svg_element(tr, xpos, ypos):
    etext = ''
    if tr.start:
        etext += svg_use('start', xpos, ypos)
        xpos += sdata.bitw

    if tr.read and not tr.mvalue:
        for n in range(0, 1 if tr.tag else tr.fbyte):
            acktype = 'ackh' if (n < tr.fbyte - 1) or tr.rcont else 'nackh'
            t, xpos = svg_rdbyte(xpos, ypos, acktype,
                                 tr.tag if tr.tag else 'D' + str(n + 1))
            etext += t
            if xpos > sdata.wrap and (n < tr.fbyte - 1):
                xpos = sdata.cindent
                ypos += sdata.linesep
    elif tr.read and tr.mvalue:
        # need space to draw three byte+ack and a break squiggle
        if (xpos + (sdata.bytew + sdata.bitw) * 3 + sdata.bitw) > sdata.wrap:
            xpos = sdata.cindent
            ypos += sdata.linesep
        t, xpos = svg_rdbyte(xpos, ypos, 'ackh', 'Data1')
        etext += t
        t, xpos = svg_rdbyte(xpos, ypos, 'ackh', 'Data2')
        etext += t
        etext += svg_use('skip', xpos, ypos)
        xpos += sdata.bitw
        t, xpos = svg_rdbyte(xpos, ypos, 'nackh', 'DataN')
        etext += t

    elif tr.adr:
        etext += svg_use('adr' + str(tr.fbyte), xpos, ypos)
        xpos += sdata.bytew
        etext += svg_use('ackd', xpos, ypos)
        xpos += sdata.bitw
    elif tr.mvalue:
        # need space to draw three byte+ack and a break squiggle
        if (xpos + (sdata.bytew + sdata.bitw) * 3 + sdata.bitw) > sdata.wrap:
            xpos = sdata.cindent
            ypos += sdata.linesep
        t, xpos = svg_wrbyte(xpos, ypos, tr.nackok, 'Data1')
        etext += t
        t, xpos = svg_wrbyte(xpos, ypos, tr.nackok, 'Data2')
        etext += t
        etext += svg_use('skip', xpos, ypos)
        xpos += sdata.bitw
        t, xpos = svg_wrbyte(xpos, ypos, tr.nackok, 'DataN')
        etext += t

    elif tr.start:  # and not tr.adr by position in elif
        etext += svg_use('adr' + str(tr.fbyte & 1), xpos, ypos)
        etext += '    <text x="' + str(xpos + 115)
        etext += '" y="' + str(ypos + sdata.txty) + '">' + hex(tr.fbyte >> 1)
        etext += '</text>\n'
        xpos += sdata.bytew
        etext += svg_use('ackd', xpos, ypos)
        xpos += sdata.bitw

    else:
        t, xpos = svg_wrbyte(xpos, ypos, tr.nackok,
                             tr.tag if tr.tag else hex(tr.fbyte))
        etext += t

    if tr.stop:
        etext += svg_use('pstop', xpos, ypos)
        xpos += sdata.bitw

    return etext, xpos, ypos


# since they are referenced by href name the style and defs only
# go in the first svg in a file
first_svg = True


def out_svg(outfile, svg, ypos, svgtext):
    global first_svg
    outfile.write('<svg\n' + sdata.svgtag_consts)
    outfile.write('viewBox="0 0 ' + str(sdata.svgw) + ' ' +
                  str(ypos + sdata.linesep + 8) + '">\n')
    if (first_svg):
        outfile.write(sdata.svgstyle + sdata.svg_defs)
        first_svg = False
    outfile.write(svg)
    if svgtext:
        outfile.write('<text x="10" y="' + str(ypos + sdata.linesep + 3))
        outfile.write('" class="tt">' + svgtext[:-2] + '</text>\n')
    outfile.write('</svg>\n')


def output_svg(outfile, transactions, title):
    xpos = 0
    ypos = 0
    svg = ''
    svgtext = ''
    for tr in transactions:
        if isinstance(tr, str):
            if svg:
                out_svg(outfile, svg, ypos, svgtext)
            if title:
                outfile.write('<h2>' + tr + '</h2>\n')
            xpos = 0
            ypos = 0
            svg = ''
            svgtext = ''
            continue
        if xpos > sdata.wrap:
            xpos = sdata.cindent
            ypos += sdata.linesep
        trsvg, xpos, ypos = svg_element(tr, xpos, ypos)
        svgtext += text_element(tr, ', ', False)
        svg += trsvg

    out_svg(outfile, svg, ypos, svgtext)
