"""
Vault-aware SSH connection helper.

Intercepts the WebSocket connect message and injects vault-resolved
credentials into the SSHConfig before Paramiko sees it. Secrets never
cross the WebSocket — the browser sends a credential_name or hostname,
the server resolves and injects.

Usage in app.py WebSocket handler:
    from nterm.vault_connect import resolve_ssh_config

    # Inside the WebSocket connect handler, before SSH connection:
    config = resolve_ssh_config(connect_msg, resolver)
    # config now has credentials populated from vault if available
"""

from __future__ import annotations
import logging
from typing import Optional

logger = logging.getLogger(__name__)


def resolve_ssh_config(
    connect_msg: dict,
    resolver,
) -> dict:
    """
    Enrich a WebSocket connect message with vault credentials.

    The connect message from the browser contains:
        {
            "type": "connect",
            "hostname": "...",
            "port": 22,
            "username": "...",        # may be empty if vault resolves
            "password": "...",        # may be empty if vault resolves
            "key_path": "...",        # may be empty
            "key_data": "...",        # may be empty
            "credential_name": "...", # optional: explicit vault credential
            "use_vault": true,        # optional: try vault resolution
            "legacy_mode": false,
            ...
        }

    Resolution priority:
        1. Explicit credential_name → resolve that specific credential
        2. use_vault=true with hostname → pattern-match from vault
        3. Credentials already in message → pass through unchanged

    Returns the enriched connect_msg dict with credentials populated.
    Secrets are injected server-side — they never cross the WebSocket.
    """
    if resolver is None:
        return connect_msg

    hostname = connect_msg.get("hostname", "")
    port = connect_msg.get("port", 22)
    credential_name = connect_msg.get("credential_name")
    use_vault = connect_msg.get("use_vault", False)

    # Already has explicit credentials — skip vault
    has_password = bool(connect_msg.get("password"))
    has_key = bool(connect_msg.get("key_content") or connect_msg.get("key_file"))

    if has_password or has_key:
        if not credential_name:
            # User provided creds manually, don't override
            return connect_msg

    # Check vault availability
    if not resolver.is_initialized() or not resolver.store.is_unlocked:
        logger.debug("Vault not available for credential resolution")
        return connect_msg

    profile = None

    try:
        if credential_name:
            # Explicit credential requested
            profile = resolver.create_profile_for_credential(
                credential_name, hostname, port
            )
            logger.info(f"Resolved explicit credential '{credential_name}' for {hostname}")

        elif use_vault:
            # Pattern-match from vault
            profile = resolver.resolve_or_default(hostname, port=port)
            if profile:
                logger.info(f"Vault matched credential for {hostname}")
            else:
                logger.debug(f"No vault credential matched {hostname}")
                return connect_msg
        else:
            return connect_msg

    except Exception as e:
        logger.error(f"Vault resolution failed for {hostname}: {e}")
        return connect_msg

    if profile is None:
        return connect_msg

    # Inject resolved credentials into the connect message
    enriched = dict(connect_msg)

    if profile.primary_username:
        enriched["username"] = profile.primary_username

    if profile.auth_methods:
        auth = profile.auth_methods[0]
        method_name = auth.method.name

        if method_name == "PASSWORD":
            enriched["password"] = auth.password
            enriched["auth_method"] = "password"

        elif method_name == "KEY_STORED":
            # key_content matches SSHConfig.key_content (PEM string)
            enriched["key_content"] = auth.key_data
            enriched["key_passphrase"] = auth.key_passphrase
            enriched["auth_method"] = "key_paste"

        elif method_name == "KEY_FILE":
            # key_file matches SSHConfig.key_file (server path)
            enriched["key_file"] = auth.key_path
            enriched["key_passphrase"] = auth.key_passphrase
            enriched["auth_method"] = "key_file"

        elif method_name == "AGENT":
            enriched["auth_method"] = "agent"

    # Mark that credentials came from vault (for status display)
    enriched["_vault_resolved"] = True
    enriched["_credential_name"] = credential_name or profile.name

    return enriched