"""Regenerate the <nav> of every static META 2027 page from one definition.

The seven hand-maintained nav variants differed only by the brand href, the `scrolled` class and
which link was active — and that divergence is exactly how menus rot. One source, one sweep, and
the per-page differences become computed instead of remembered.

Only the region between <nav ...> and </nav> changes; the opening tag itself is preserved so
home.html keeps its transparent header and the subpages keep `scrolled`. Everything outside the
nav is untouched, which the md5 report at the end demonstrates.
"""

import glob
import hashlib
import os
import re

# (label, href, [(sublabel, subhref), ...] or None)
MENU = [
    ('Program', 'programme.html', [
        ('Important Dates', 'dates.html'),
        ('Scientific Program', 'programme.html'),
        ('Plenary &amp; Keynote Lectures', 'speakers.html'),
        ('Symposia', 'symposia.html'),
        ('Special Sessions', 'special-sessions.html'),
        ('META Quantum Workshop', 'workshop.html'),
        ('Tutorials', 'tutorials.html'),
    ]),
    ('Submit', 'submit.html', [
        ('Call for Papers', 'submit.html#call-for-papers'),
        ('Submission Guidelines', 'submit.html#guidelines'),
        ('Templates', 'submit.html#templates'),
        ('Submit a Paper', 'portal.html'),
    ]),
    ('Attend', 'attend.html', [
        ('Registration', 'registration.html'),
        ('Venue &amp; Travel', 'attend.html#venue'),
        ('Accommodation', 'accommodation.html'),
        ('Visa &amp; Entry', 'visa.html'),
    ]),
    ('About', 'about.html', [
        ('About META', 'about.html'),
        ('Committees', 'committees.html'),
        ('Awards', 'awards.html'),
        ('Proceedings', 'proceedings.html'),
        ('Partners', 'partners.html'),
        ('Past Editions', 'editions.html'),
        ('FAQ', 'faq.html'),
    ]),
    ('Exhibits &amp; Sponsorships', 'sponsors.html', None),
]

# Which top-level entry lights up on which page. Pages reachable only from the footer
# (ethics, promote) light nothing: pretending they live under About would be a small lie.
ACTIVE = {
    'programme.html': 'Program', 'dates.html': 'Program', 'symposia.html': 'Program',
    'tutorials.html': 'Program', 'special-sessions.html': 'Program', 'workshop.html': 'Program',
    'speakers.html': 'Program',
    'submit.html': 'Submit',
    'attend.html': 'Attend', 'registration.html': 'Attend',
    'accommodation.html': 'Attend', 'visa.html': 'Attend',
    'about.html': 'About', 'committees.html': 'About', 'awards.html': 'About',
    'proceedings.html': 'About', 'faq.html': 'About',
    'partners.html': 'About',
    'editions.html': 'About',
    'sponsors.html': 'Exhibits &amp; Sponsorships',
}


def build_nav(page):
    active = ACTIVE.get(page)
    brand_href = './'
    parts = ['  <a class="brand" href="%s">META&nbsp;<span>2027</span></a>' % brand_href,
             '  <div class="navlinks" id="main-menu">']
    for label, href, sub in MENU:
        cls = ' class="active"' if label == active else ''
        if sub:
            parts.append('    <div class="nav-item">')
            parts.append('      <a href="%s"%s>%s <span class="caret">&#9662;</span></a>'
                         % (href, cls, label))
            parts.append('      <div class="sub">')
            for sl, sh in sub:
                parts.append('        <a href="%s">%s</a>' % (sh, sl))
            parts.append('      </div>')
            parts.append('    </div>')
        else:
            parts.append('    <a href="%s"%s>%s</a>' % (href, cls, label))
    parts.append('  </div>')
    parts.append('  <a class="nav-portal" href="portal.html">Author&nbsp;Portal</a>')
    # "Registration", not "Register Now": registration is not open yet, and a button that
    # commands an action nobody can take yet overpromises.
    parts.append('  <a class="nav-cta" href="registration.html">Registration</a>')
    parts.append('  <button class="burger" aria-label="Menu" aria-expanded="false" '
                 'aria-controls="main-menu" onclick="const n=document.getElementById(\'topnav\');'
                 'const o=n.classList.toggle(\'open\');this.setAttribute(\'aria-expanded\',o?\'true\':\'false\')">&#9776;</button>')
    return '\n'.join(parts)


changed, untouched = [], []
for f in sorted(glob.glob('*.html')):
    if f == 'meta26_program_inject.html':   # 2026 archive fragment, handled in the OJS batch
        untouched.append(f)
        continue
    s = open(f, encoding='utf-8').read()
    before = hashlib.md5(s.encode()).hexdigest()
    m = re.search(r'(<nav\b[^>]*>).*?(</nav>)', s, re.S)
    if not m:
        print('%-26s SANS <nav> — ignoré' % f)
        continue
    out = s[:m.start()] + m.group(1) + '\n' + build_nav(f) + '\n' + m.group(2) + s[m.end():]
    if hashlib.md5(out.encode()).hexdigest() != before:
        open(f, 'w', encoding='utf-8').write(out)
        changed.append(f)
    else:
        untouched.append(f)

print('réécrites : %d — %s' % (len(changed), ', '.join(changed)))
print('intactes  : %d' % len(untouched))
