"""
Native Messaging Host for Browser Bridge

This script implements Chrome's Native Messaging protocol for direct
communication between the browser extension and external applications.

Note: The primary interface is via HTTP through the Mem App API.
This native messaging host is provided for advanced use cases requiring
direct extension communication.

Chrome Native Messaging Protocol:
- Messages are length-prefixed (4 bytes, little-endian)
- Messages are JSON encoded
- stdin/stdout are used for communication
"""

import json
import struct
import sys
from typing import Any


def read_message() -> dict[str, Any] | None:
    """
    Read a message from stdin using Chrome's native messaging protocol.

    The message format is:
    - 4 bytes: message length (little-endian uint32)
    - N bytes: JSON message

    Returns:
        Parsed message dict or None if EOF
    """
    # Read the message length (4 bytes, little-endian)
    raw_length = sys.stdin.buffer.read(4)
    if len(raw_length) != 4:
        return None

    # Unpack the length
    message_length = struct.unpack("<I", raw_length)[0]

    # Read the message content
    message_content = sys.stdin.buffer.read(message_length)
    if len(message_content) != message_length:
        return None

    # Parse the JSON message
    return json.loads(message_content.decode("utf-8"))


def send_message(message: dict[str, Any]) -> None:
    """
    Send a message to stdout using Chrome's native messaging protocol.

    Args:
        message: Message dict to send
    """
    # Encode the message as JSON
    encoded_message = json.dumps(message).encode("utf-8")

    # Write the message length (4 bytes, little-endian)
    sys.stdout.buffer.write(struct.pack("<I", len(encoded_message)))

    # Write the message content
    sys.stdout.buffer.write(encoded_message)
    sys.stdout.buffer.flush()


def handle_command(command: dict[str, Any]) -> dict[str, Any]:
    """
    Handle a command from the extension.

    This is a placeholder - the actual command handling is done
    by the browser extension. This host just forwards commands
    to the Mem App API.

    Args:
        command: Command dict with 'action' and optional 'params'

    Returns:
        Response dict
    """
    import httpx

    action = command.get("action", "")
    params = command.get("params", {})
    request_id = command.get("requestId")

    try:
        # Forward to Mem App API
        with httpx.Client(timeout=30.0) as client:
            response = client.post(
                "http://127.0.0.1:14242/api/browser-bridge",
                json={"action": action, "params": params},
            )
            response.raise_for_status()
            data = response.json()

            return {
                "requestId": request_id,
                "response": data,
            }
    except Exception as e:
        return {
            "requestId": request_id,
            "response": {
                "success": False,
                "error": str(e),
                "timestamp": __import__("datetime").datetime.now().isoformat(),
            },
        }


def main() -> None:
    """
    Main entry point for the native messaging host.

    Reads messages from stdin, processes them, and sends responses to stdout.
    """
    while True:
        message = read_message()
        if message is None:
            # EOF - extension disconnected
            break

        # Get the command from the message
        command = message.get("command", message)

        # Handle the command
        response = handle_command(command)

        # Send the response
        send_message(response)


def install_manifest(
    extension_id: str,
    host_path: str | None = None,
) -> str:
    """
    Generate and install the native messaging host manifest.

    Args:
        extension_id: Chrome extension ID (from chrome://extensions)
        host_path: Path to this script (defaults to current module)

    Returns:
        Path to installed manifest
    """
    import os
    import platform

    # Default host path to this module
    if host_path is None:
        host_path = os.path.abspath(__file__)

    # Create the manifest
    manifest = {
        "name": "com.nowledge.browser",
        "description": "Nowledge Browser Bridge - Browser control for AI agents",
        "path": host_path,
        "type": "stdio",
        "allowed_origins": [f"chrome-extension://{extension_id}/"],
    }

    # Determine manifest path based on OS
    system = platform.system()
    if system == "Darwin":
        # macOS
        manifest_dir = os.path.expanduser(
            "~/Library/Application Support/Google/Chrome/NativeMessagingHosts"
        )
    elif system == "Linux":
        manifest_dir = os.path.expanduser("~/.config/google-chrome/NativeMessagingHosts")
    elif system == "Windows":
        # Windows uses registry, not file-based manifests
        raise NotImplementedError("Windows manifest installation not yet supported")
    else:
        raise RuntimeError(f"Unsupported platform: {system}")

    # Create the directory if it doesn't exist
    os.makedirs(manifest_dir, exist_ok=True)

    # Write the manifest
    manifest_path = os.path.join(manifest_dir, "com.nowledge.browser.json")
    with open(manifest_path, "w") as f:
        json.dump(manifest, f, indent=2)

    print(f"Manifest installed to: {manifest_path}")
    return manifest_path


if __name__ == "__main__":
    import sys

    if len(sys.argv) > 1 and sys.argv[1] == "install":
        if len(sys.argv) < 3:
            print("Usage: python -m browse_now.native_host install <extension_id>")
            sys.exit(1)
        install_manifest(sys.argv[2])
    else:
        main()
