"""Headless tests for the embedded-terminal HTML shell builder.

Pure string building (no gi/WebKit), so runs under the normal harness.
"""
from sshpilot.xterm_shell import build_shell_html, asset_dir


def test_self_contained_no_cdn():
    html = build_shell_html()
    assert "cdn.jsdelivr" not in html and "cdnjs" not in html
    assert "socket.io" not in html


def test_inlines_core_and_addons():
    html = build_shell_html()
    # xterm core global + all three addon globals must be present inline
    assert "Terminal" in html
    assert "FitAddon" in html
    assert "WebLinksAddon" in html
    assert "SearchAddon" in html
    # sizable (core alone is ~280 KB)
    assert len(html) > 200_000


def test_bridge_wiring_present():
    html = build_shell_html()
    assert "window.webkit.messageHandlers.sshpilotPty.postMessage" in html
    assert '"type": "input"' in html or "type: \"input\"" in html or "type:\"input\"" in html
    assert 'send({ type: "ready"' in html or 'type: "ready"' in html
    # Ready is synchronous after fit; one rAF refines size/focus (not double-rAF).
    assert "requestAnimationFrame" in html
    # Bulk preready flush helper (base64 → term.write once).
    assert "window.termWriteB64" in html
    # Flow control write + ack (xterm.js flowcontrol guide).
    assert "window.termWrite" in html
    assert 'type: "write-ack"' in html
    # SearchAddon helper + result events.
    assert "window.sshpilotSearch" in html
    assert 'type: "search-result"' in html
    assert 'type: "search-results"' in html
    # Decorations need proposed API (SearchAddon match highlights).
    assert '"allowProposedApi": true' in html
    # Sticky scroll: only scrollToBottom when already at bottom.
    assert "_isAtBottom" in html
    assert "scrollToBottom" in html
    # WebLinks must bridge to Python — default window.open() is blocked in WebKitGTK.
    assert 'type: "open-url"' in html or "type: \"open-url\"" in html
    # Hover/leave feed TerminalWidget._hovered_hyperlink_uri for Open/Copy Link.
    assert 'type: "link-hover"' in html
    assert 'type: "link-leave"' in html


def test_clipboard_shortcuts_are_owned_once_and_respect_passthrough():
    html = build_shell_html()
    assert "window.sshpilotShortcutPassthrough" in html
    assert "const isMac = /Mac|iPhone|iPad/" in html
    assert "isMac ? e.metaKey : (e.ctrlKey && e.shiftKey)" in html
    assert 'if (k === "c")' in html
    assert 'k === "c" || k === "x"' not in html
    assert 'type: "paste"' in html
    assert 'type: "copy"' in html
    assert 'type: "selection-changed"' in html


def test_link_handler_matches_xterm_docs_pattern():
    """Shared ILinkHandler for WebLinks + OSC 8 (xtermjs.org link-handling guide)."""
    html = build_shell_html()
    assert "const linkHandler" in html
    assert "term.options.linkHandler = linkHandler" in html
    assert "new WebLinksAddon.WebLinksAddon(activateLink, linkHandler)" in html
    assert "allowNonHttpProtocols: false" in html
    # Modifier required to open (Ctrl / Cmd).
    assert "event.metaKey" in html
    assert "event.ctrlKey" in html
    assert "function activateLink" in html


def test_theme_and_font_seeded():
    html = build_shell_html(theme={"background": "#112233"}, font_family="Fira", font_size=15)
    assert "#112233" in html
    assert "Fira" in html
    assert "15" in html


def test_autocomplete_popup_present():
    html = build_shell_html()
    assert 'id="ac"' in html
    assert "window.sshpilotAC" in html
    assert "sshpilotAC.visible()" in html  # key handler consults the popup
    assert "e.preventDefault()" in html
    assert "sshpilotAC.key(e)" in html
    # Suggestion-only: no auto-highlight; Tab passes through; Enter needs selection.
    assert "sel = -1" in html
    assert 'e.key === "Tab" || e.key === "ArrowRight") return true' in html
    assert "hasSelection()" in html
    # Bottom-of-terminal: flip above the real cursor box (helper textarea).
    assert "placeAbove" in html
    assert "xterm-helper-textarea" in html
    assert "cursorTop - gap - h" in html
    # Bold + distinct panel (lifted bg, accent border, solid selection).
    assert "font-weight:700" in html or "font-weight: 700" in html
    assert "--ac-accent" in html
    assert "--ac-sel-fg" in html
    assert "liftHex" in html


def test_asset_dir_exists():
    # Either the system libjs-xterm or the bundled copy must resolve to real files.
    import os
    d = asset_dir()
    assert os.path.isfile(os.path.join(d, "xterm.js"))
