"""
Network utilities for security validation.

Provides functions for detecting VM host (gateway) and validating
that Ollama connections only go to trusted destinations.
"""
import socket
import subprocess
import re
from typing import Optional, Tuple
from urllib.parse import urlparse


def get_default_gateway() -> Optional[str]:
    """
    Get the default gateway IP address.

    On a VM, the default gateway is typically the host machine.

    Returns:
        Gateway IP address or None if detection fails
    """
    try:
        # Try using 'ip route' (Linux)
        result = subprocess.run(
            ['ip', 'route', 'show', 'default'],
            capture_output=True,
            text=True,
            timeout=5
        )
        if result.returncode == 0:
            # Parse: "default via 10.0.0.1 dev eth0 ..."
            match = re.search(r'default via (\d+\.\d+\.\d+\.\d+)', result.stdout)
            if match:
                return match.group(1)
    except (subprocess.TimeoutExpired, FileNotFoundError):
        pass

    try:
        # Fallback: 'route -n' (older Linux)
        result = subprocess.run(
            ['route', '-n'],
            capture_output=True,
            text=True,
            timeout=5
        )
        if result.returncode == 0:
            for line in result.stdout.split('\n'):
                if line.startswith('0.0.0.0'):
                    parts = line.split()
                    if len(parts) >= 2:
                        return parts[1]
    except (subprocess.TimeoutExpired, FileNotFoundError):
        pass

    try:
        # Fallback: netifaces if available
        import netifaces
        gateways = netifaces.gateways()
        default = gateways.get('default', {})
        if netifaces.AF_INET in default:
            return default[netifaces.AF_INET][0]
    except ImportError:
        pass

    return None


def extract_host_from_url(url: str) -> Optional[str]:
    """
    Extract the host/IP from a URL.

    Args:
        url: URL like 'http://10.0.0.28:11434'

    Returns:
        Host/IP portion or None
    """
    try:
        parsed = urlparse(url)
        return parsed.hostname
    except Exception:
        return None


def is_localhost(host: str) -> bool:
    """Check if host is localhost."""
    if not host:
        return False
    return host in ('localhost', '127.0.0.1', '::1')


def is_valid_ollama_host(url: str) -> Tuple[bool, str]:
    """
    Validate that an Ollama URL points to a trusted destination.

    Only allows:
    - localhost (127.0.0.1, localhost)
    - Default gateway (VM host)

    Args:
        url: Ollama URL to validate

    Returns:
        Tuple of (is_valid, reason)
    """
    host = extract_host_from_url(url)

    if not host:
        return False, "Could not parse URL"

    # Localhost is always allowed
    if is_localhost(host):
        return True, "localhost"

    # Check if it's the default gateway (VM host)
    gateway = get_default_gateway()

    if gateway is None:
        return False, "Could not detect gateway. Only localhost allowed."

    if host == gateway:
        return True, "VM host (gateway)"

    # Block everything else
    return False, f"Only localhost or VM host ({gateway}) allowed. Got: {host}"


def get_ollama_host_info() -> dict:
    """
    Get information about allowed Ollama hosts.

    Returns:
        Dict with gateway info and allowed hosts
    """
    gateway = get_default_gateway()

    return {
        'gateway': gateway,
        'allowed_hosts': ['localhost', '127.0.0.1'] + ([gateway] if gateway else []),
        'gateway_detected': gateway is not None
    }
