"""Terminal approval for first-time bridge pairing (trust on first use).

The pairing token is the security boundary between a browser tab and this
daemon. To avoid a manual copy-paste, a tokenless browser asks to pair and the
human approves here, at the terminal where they launched the bridge. A rogue web
page can trigger this prompt, but its origin is shown and the human rejects it.
"""

from __future__ import annotations

import asyncio
import sys  # module-level name so tests can monkeypatch pairing.sys.stdin

# Serialise prompts so two concurrent pair requests do not interleave on stdin.
_prompt_lock = asyncio.Lock()


async def approve(origin: str, roots_desc: str, *, timeout: float = 60.0) -> bool:
    """Ask the human at the bridge terminal to approve a pairing request.

    Returns True only on an explicit y/yes. Returns False immediately when stdin
    is not a TTY (headless bridge — caller falls back to the printed token), and
    on an n / blank / timeout / EOF.
    """
    stdin = sys.stdin
    if stdin is None or not stdin.isatty():
        return False

    prompt = (
        "\nAtashi wants to pair with this bridge.\n"
        f"  Origin: {origin}\n"
        f"  It will be allowed to read, edit and run commands in: {roots_desc}\n"
        "  Approve? [y/N] "
    )
    async with _prompt_lock:
        try:
            answer = await asyncio.wait_for(asyncio.to_thread(input, prompt), timeout)
        except (asyncio.TimeoutError, EOFError):
            return False
    return answer.strip().lower() in {"y", "yes"}
