# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import logging as log
import re
from typing import List, Match, Optional, Set

def get_reg_link(rname: str) -> str:
    '''Return regname with a HTML link to itself'''
    return '<a href="#Reg_{}">{}</a>'.format(rname.lower(), rname)


def expand_paras(s: str, rnames: Set[str]) -> List[str]:
    '''Expand a description field to HTML.

    This supports a sort of simple pseudo-markdown. Supported Markdown
    features:

    - Separate paragraphs on a blank line
    - **bold** and *italicised* text
    - Back-ticks for pre-formatted text

    We also generate links to registers when a name is prefixed with a double
    exclamation mark. For example, if there is a register FOO then !!FOO or
    !!FOO.field will generate a link to that register.

    Returns a list of rendered paragraphs

    '''
    # Start by splitting into paragraphs. The regex matches a newline followed
    # by one or more lines that just contain whitespace. Then render each
    # paragraph with the _expand_paragraph worker function.
    paras = [_expand_paragraph(paragraph.strip(), rnames)
             for paragraph in re.split(r'\n(?:\s*\n)+', s)]

    # There will always be at least one paragraph (splitting an empty string
    # gives [''])
    assert paras
    return paras


def _expand_paragraph(s: str, rnames: Set[str]) -> str:
    '''Expand a single paragraph, as described in _get_desc_paras'''
    def fieldsub(match: Match[str]) -> str:
        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)

    # Split out pre-formatted text. Because the call to re.split has a capture
    # group in the regex, we get an odd number of results. Elements with even
    # indices are "normal text". Those with odd indices are the captured text
    # between the back-ticks.
    code_split = re.split(r'`([^`]+)`', s)
    expanded_parts = []

    for idx, part in enumerate(code_split):
        if idx & 1:
            # Text contained in back ticks
            expanded_parts.append('<code>{}</code>'.format(part))
            continue

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

    return '<p>{}</p>'.format(''.join(expanded_parts))


def render_td(s: str, rnames: Set[str], td_class: Optional[str]) -> str:
    '''Expand a description field and put it in a <td>.

    Returns a string. See _get_desc_paras for the format that gets expanded.

    '''
    desc_paras = expand_paras(s, rnames)
    class_attr = '' if td_class is None else ' class="{}"'.format(td_class)
    return '<td{}>{}</td>'.format(class_attr, ''.join(desc_paras))
