"""Register definition (ids.json) → HTML tables."""
import json
from html import escape


MODULE_ORDER = [
    'SYS_REG', 'SYS_ANA', 'SYS_PLL',
    'DAQ_REG', 'DAQ_PAR', 'DAQ_FLT',
    'AWG_REG', 'TRIG_CTRL', 'PUMP_REG', 'MIXER_REG',
]

MODULE_DESC = {
    'SYS_REG': '系统控制寄存器', 'SYS_ANA': '模拟配置寄存器',
    'SYS_PLL': 'PLL 配置寄存器', 'DAQ_REG': 'DAQ 控制寄存器',
    'DAQ_PAR': 'DAQ 读出参数配置', 'DAQ_FLT': 'DAQ 匹配滤波器系数',
    'AWG_REG': 'AWG 控制寄存器', 'TRIG_CTRL': '触发控制寄存器',
    'PUMP_REG': 'Pump 控制寄存器', 'MIXER_REG': '混频器控制寄存器',
}


def eh(s):
    return escape(str(s))


def _bits_str(bits):
    if not bits:
        return ''
    if len(bits) == 1 or bits[0] == bits[-1]:
        return f'[{bits[0]}]'
    return f'[{bits[0]}:{bits[-1]}]'


def _range_str(r):
    if not r or not r.get('value'):
        return ''
    t, v = r.get('type', 'str'), r.get('value', '')
    if t == 'str':
        if v == 'ANY':
            return '<em>任意</em>'
        if v == 'NA':
            return '<em>—</em>'
        return eh(str(v))
    if t == 'list' and isinstance(v, list):
        return f'{v[0]} ~ {v[1]}'
    if t == 'set' and isinstance(v, list):
        return ', '.join(str(x) for x in v)
    return eh(str(v))


def _perm_badge(p):
    badges = {
        'RW': '<span class="perm-rw">RW</span>',
        'RO': '<span class="perm-ro">RO</span>',
        'WC': '<span class="perm-wc">WC</span>',
    }
    return badges.get(p, eh(p))


def render(json_path):
    """Load ids.json and render all register tables as HTML."""
    with open(json_path, encoding='utf-8') as f:
        data = json.load(f)
    modules = data.get('Modules', {})

    html = []
    for mod_name in MODULE_ORDER:
        if mod_name not in modules:
            continue
        entries = modules[mod_name]
        desc = MODULE_DESC.get(mod_name, '')
        html.append(
            f'<h3 id="reg-{mod_name.lower()}">{mod_name} — {desc}</h3>'
        )
        html.append(f'<p>共 {len(entries)} 个寄存器/存储段。</p>')

        for seg_name, seg in entries.items():
            addr = seg.get('OffsetAddress', '')
            perm = seg.get('Permission', '')
            sd = seg.get('SegDescription', '')
            fields = seg.get('Fields', [])

            html.append(
                f'<h4 id="reg-{seg_name}">{seg_name.upper()}</h4>'
            )
            html.append(
                f'<p class="reg-summary">'
                f'<strong>偏移地址：</strong><code>{eh(addr)}</code> '
                f'<strong>权限：</strong>{_perm_badge(perm)} '
                f'<strong>描述：</strong>{eh(sd)}</p>'
            )

            if fields:
                html.append(
                    '<table class="compact"><thead><tr>'
                    '<th style="width:11%">Bits</th>'
                    '<th style="width:18%">Field Name</th>'
                    '<th style="width:14%">Reset Value</th>'
                    '<th style="width:12%">Range</th>'
                    '<th>Description</th>'
                    '</tr></thead><tbody>'
                )
                for f in fields:
                    b = f.get('Bits', [])
                    html.append(
                        f'<tr>'
                        f'<td class="bits">{_bits_str(b)}</td>'
                        f'<td class="text-mono">{eh(f.get("FieldName", ""))}</td>'
                        f'<td class="reset-val">{eh(f.get("ResetValue", ""))}</td>'
                        f'<td>{_range_str(f.get("Range"))}</td>'
                        f'<td>{eh(f.get("FieldDescription", ""))}</td>'
                        f'</tr>'
                    )
                html.append('</tbody></table>')
        html.append('')
    return '\n'.join(html)
