# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
"""
Generate html documentation from validated register json tree
"""

import logging as log
import re
import sys


def genout(outfile, msg):
    outfile.write(msg)


# expand !!register references into html links, gen **bold** and *italic*
def desc_expand(s, rnames):
    def fieldsub(match):
        base = match.group(1).partition('.')[0].lower()
        if base in rnames:
            if match.group(1)[-1] == ".":
                return ('<a href="#Reg_' + base + '"><code class=\"reg\">' +
                        match.group(1)[:-1] + '</code></a>.')
            else:
                return ('<a href="#Reg_' + base + '"><code class=\"reg\">' +
                        match.group(1) + '</code></a>')
        log.warn('!!' + match.group(1).partition('.')[0] +
                 ' not found in register list.')
        return match.group(0)

    s = re.sub(r"!!([A-Za-z0-9_.]+)", fieldsub, s)
    s = re.sub(r"(?s)\*\*(.+?)\*\*", r'<B>\1</B>', s)
    s = re.sub(r"\*([^*]+?)\*", r'<I>\1</I>', s)
    return s


# Generation of HTML table with register bit-field summary picture
# Max 16-bit wide on one line


def gen_tbl_row(outfile, msb, width, close):
    if (close):
        genout(outfile, "</tr>\n")
    genout(outfile, "<tr>")
    for x in range(msb, msb - width, -1):
        genout(outfile, "<td class=\"bitnum\">" + str(x) + "</td>")

    genout(outfile, "</tr><tr>")


def gen_html_reg_pic(outfile, reg, width):

    if (width > 32):
        bsize = 3
        nextbit = 63
        hdrbits = 16
        nextline = 48
    elif (width > 16):
        bsize = 3
        nextbit = 31
        hdrbits = 16
        nextline = 16
    elif (width > 8):
        bsize = 3
        nextbit = 15
        nextline = 0
        hdrbits = 16
    else:
        bsize = 12
        nextbit = 7
        nextline = 0
        hdrbits = 8

    genout(outfile, "<table class=\"regpic\">")
    gen_tbl_row(outfile, nextbit, hdrbits, False)

    for field in reversed(reg['fields']):
        fieldlsb = field['bitinfo'][2]
        fieldwidth = field['bitinfo'][1]
        fieldmsb = fieldlsb + fieldwidth - 1
        fname = field['name']

        while nextbit > fieldmsb:
            if (nextbit >= nextline) and (fieldmsb < nextline):
                spans = nextbit - (nextline - 1)
            else:
                spans = nextbit - fieldmsb
            genout(
                outfile, "<td class=\"unused\" colspan=" + str(spans) +
                ">&nbsp;</td>\n")
            if (nextbit >= nextline) and (fieldmsb < nextline):
                nextbit = nextline - 1
                gen_tbl_row(outfile, nextbit, hdrbits, True)
                nextline = nextline - 16
            else:
                nextbit = fieldmsb

        while (fieldmsb >= nextline) and (fieldlsb < nextline):
            spans = fieldmsb - (nextline - 1)
            genout(
                outfile, "<td class=\"fname\" colspan=" + str(spans) + ">" +
                fname + "...</td>\n")
            fname = "..." + field['name']
            fieldwidth = fieldwidth - spans
            fieldmsb = nextline - 1
            nextline = nextline - 16
            gen_tbl_row(outfile, fieldmsb, hdrbits, True)

        namelen = len(fname)
        if namelen == 0 or fname == ' ': fname = "&nbsp;"
        if (namelen > bsize * fieldwidth):
            usestyle = (" style=\"font-size:" + str(
                (bsize * 100 * fieldwidth) / namelen) + "%\"")
        else:
            usestyle = ""

        genout(
            outfile, "<td class=\"fname\" colspan=" + str(fieldwidth) +
            usestyle + ">" + fname + "</td>\n")

        if (fieldlsb == nextline) and nextline > 0:
            gen_tbl_row(outfile, nextline - 1, hdrbits, True)
            nextline = nextline - 16

        nextbit = fieldlsb - 1
    while (nextbit > 0):
        spans = nextbit - (nextline - 1)
        genout(outfile,
               "<td class=\"unused\" colspan=" + str(spans) + ">&nbsp;</td>\n")
        nextbit = nextline - 1
        if (nextline > 0):
            gen_tbl_row(outfile, nextline - 1, hdrbits, True)
            nextline = nextline - 16

    genout(outfile, "</tr></table>")


# Generation of HTML table with header, register picture and details


def gen_html_register(outfile, reg, comp, width, rnames, toc, toclvl):
    def gen_merge(outfile, fieldlsb, mergebase, mergeprev, mergedesc):
        genout(
            outfile, "<tr><td class=\"regbits\">" + str(fieldlsb - 1) + ':' +
            str(mergebase) + "</td>")
        genout(outfile, "<td class=\"regperm\"></td>")
        genout(outfile, "<td class=\"regrv\"></td>")
        genout(outfile, "<td class=\"regfn\"></td>")
        if mergeprev != mergedesc:
            genout(outfile,
                   "<td class=\"regde\">" + mergedesc + ".." + mergeprev[4:])
        else:
            genout(outfile, "<td class=\"regde\">" + mergedesc)
        genout(outfile, "</td></tr>\n")

    rname = reg['name']
    offset = reg['genoffset']
    #in a multireg with multiple regs give anchor with base register name
    if 'genbasebits' in reg and rname[-1] == '0':
        genout(outfile, "<div id=\"Reg_" + rname[:-1].lower() + "\"></div>\n")
    regwen_string = ''
    if 'regwen' in reg and (reg['regwen'] != ''):
        regwen_string = '<br>Register enable = ' + reg['regwen']
    genout(
        outfile, "<table class=\"regdef\" id=\"Reg_" + rname.lower() + "\">\n"
        "<tr><th class=\"regdef\" colspan=5>" + comp + "." + rname + " @ + " +
        hex(offset) + "<br>" + desc_expand(reg['desc'], rnames) + "<br>" +
        "Reset default = " + hex(reg['genresval']) + ", mask " + hex(
            reg['genresmask']) + regwen_string + "</th></tr>\n")
    if toc != None:
        toc.append((toclvl, comp + "." + rname, "Reg_" + rname.lower()))
    genout(outfile, "<tr><td colspan=5>")
    gen_html_reg_pic(outfile, reg, width)
    genout(outfile, "</td></tr>\n")

    genout(outfile, "<tr><th width=5%>Bits</th>")
    genout(outfile, "<th width=5%>Type</th>")
    genout(outfile, "<th width=5%>Reset</th>")
    genout(outfile, "<th>Name</th>")
    genout(outfile, "<th>Description</th></tr>")
    nextbit = 0
    fcount = 0
    mergebase = -1
    for field in reg['fields']:
        fcount += 1
        if not 'name' in field:
            fname = "field " + str(fcount)
        else:
            fname = field['name']

        fieldlsb = field['bitinfo'][2]
        if (fieldlsb > nextbit) and mergebase < 0:
            genout(outfile, "<tr><td class=\"regbits\">")
            if (nextbit == (fieldlsb - 1)):
                genout(outfile, str(nextbit))
            else:
                genout(outfile, str(fieldlsb - 1) + ":" + str(nextbit))
            genout(outfile,
                   "</td><td></td><td></td><td></td><td>Reserved</td></tr>")
        if 'genbasebits' in reg:
            if (((1 << fieldlsb) & reg['genbasebits']) == 0):
                mergeprev = field['desc']
                if (mergebase < 0):
                    mergebase = fieldlsb
                    mergedesc = field['desc']
                nextbit = fieldlsb + field['bitinfo'][1]
                continue
            else:
                if (mergebase >= 0):
                    gen_merge(outfile, fieldlsb, mergebase, mergeprev,
                              mergedesc)
                    mergebase = -1
        genout(outfile, "<tr><td class=\"regbits\">" + field['bits'] + "</td>")
        genout(outfile, "<td class=\"regperm\">" + field['swaccess'] + "</td>")
        genout(
            outfile,
            "<td class=\"regrv\">" + ('x' if field['genresvalx'] else hex(
                field['genresval'])) + "</td>")
        genout(outfile, "<td class=\"regfn\">" + fname + "</td>")
        if 'desc' in field:
            genout(
                outfile, "<td class=\"regde\">" + desc_expand(
                    field['desc'], rnames) + "\n")
        else:
            genout(outfile, "<td>\n")

        if 'enum' in field:
            genout(outfile, "    <table>")
            for enum in field['enum']:
                if (not 'name' in enum):
                    ename = "enum for " + fname + " in " + rname
                else:
                    ename = enum['name']
                genout(outfile, "    <tr><td>" + enum['value'] + "</td>")
                genout(outfile, "<td>" + ename + "</td>")
                genout(
                    outfile, "<td>" + desc_expand(enum['desc'], rnames) +
                    "</td></tr>\n")

            genout(outfile, "    </table>")
            if 'genrsvdenum' in field:
                genout(outfile, "Other values are reserved.")
        genout(outfile, "</td></tr>\n")
        nextbit = fieldlsb + field['bitinfo'][1]

    # could be in the middle of a merge
    if (mergebase >= 0):
        gen_merge(outfile, nextbit, mergebase, mergeprev, mergedesc)

    genout(outfile, "</table>\n<br><br>\n")

    return


def gen_html_window(outfile, win, comp, regwidth, rnames, toc, toclvl):
    wname = win['name']
    offset = win['genoffset']
    genout(
        outfile, '<table class="regdef" id="Reg_' + wname.lower() + '">\n'
        '<tr><th class="regdef">' + comp + '.' + wname + ' @ + ' + hex(offset)
        + '<br>' + win['items'] + ' item ' + win['swaccess'] +
        ' window<br>Byte writes are ' +
        ('' if win['genbyte-write'] else '<i>not</i> ') +
        'supported</th></tr>\n')
    genout(outfile, '<tr><td><table class="regpic">')
    genout(outfile, '<tr><td width="10%"></td>')
    wid = win['genvalidbits']

    for x in range(regwidth - 1, -1, -1):
        if x == regwidth - 1 or x == wid - 1 or x == 0:
            genout(outfile, '<td class="bitnum">' + str(x) + '</td>')
        else:
            genout(outfile, '<td class="bitnum"></td>')
    genout(outfile, '</tr>')
    tblmax = int(win['items']) - 1
    for x in [0, 1, 2, tblmax - 1, tblmax]:
        if x == 2:
            genout(
                outfile, '<tr><td>&nbsp;</td><td align=center colspan=' +
                str(regwidth) + '>...</td></tr>')
        else:
            genout(
                outfile, '<tr><td class="regbits">+' +
                hex(offset + x * (regwidth // 8)) + '</td>')
            if wid < regwidth:
                genout(
                    outfile, '<td class="unused" colspan=' +
                    str(regwidth - wid) + '>&nbsp;</td>\n')
                genout(
                    outfile,
                    '<td class="fname" colspan=' + str(wid) + '>&nbsp;</td>\n')
            else:
                genout(
                    outfile, '<td class="fname" colspan=' + str(regwidth) +
                    '>&nbsp;</td>\n')
            genout(outfile, '</tr>')
    genout(outfile, '</td></tr></table>')
    genout(
        outfile, '<tr><td class="regde">' + desc_expand(win['desc'], rnames) +
        '</td></tr>')
    genout(outfile, "</table>\n<br><br>\n")
    if toc != None:
        toc.append((toclvl, comp + "." + wname, "Reg_" + wname.lower()))


# Must have called validate, so should have no errors


def gen_html(regs, outfile, toclist=None, toclevel=3):
    component = regs['name']
    registers = regs['registers']
    rnames = regs['genrnames']

    if 'regwidth' in regs:
        regwidth = int(regs['regwidth'], 0)
    else:
        regwidth = 32

    for x in registers:
        if 'reserved' in x:
            continue

        if 'skipto' in x:
            continue

        if 'sameaddr' in x:
            for sareg in x['sameaddr']:
                gen_html_register(outfile, sareg, component, regwidth, rnames,
                                  toclist, toclevel)
            continue

        if 'window' in x:
            gen_html_window(outfile, x['window'], component, regwidth, rnames,
                            toclist, toclevel)
            continue

        if 'multireg' in x:
            for reg in x['multireg']['genregs']:
                gen_html_register(outfile, reg, component, regwidth, rnames,
                                  toclist, toclevel)
            continue

        gen_html_register(outfile, x, component, regwidth, rnames, toclist,
                          toclevel)
    return
