"""Snapper integration module for detecting snapper-managed btrfs subvolumes."""

from typing import Dict, List, Optional, Set, Tuple
from dataclasses import dataclass
#from p20260130_12_kilo01.shell_calls import (
from jusfltuls.shell_calls import (
    build_snapper_list_configs,
    build_sudo_btrfs_filesystem_show,
    run_command,
)


@dataclass
class SnapperConfig:
    """Represents a snapper configuration."""
    name: str
    subvolume: str


def is_snapper_available() -> bool:
    """Check if snapper is installed and available."""
    returncode, _ = run_command(["which", "snapper"])
    return returncode == 0


def parse_snapper_list_configs(output: str) -> List[SnapperConfig]:
    """Parse the output of 'snapper list-configs' command.

    Expected format:
        Config | Subvolume
        -------+----------
        home   | /home
    """
    configs = []
    lines = output.strip().split("\n")

    for line in lines:
        # Skip header and separator lines
        if not line or line.startswith("Config") or line.startswith("---"):
            continue

        # Parse config line (format: "name   | /path")
        parts = line.split("|")
        if len(parts) >= 2:
            name = parts[0].strip()
            subvolume = parts[1].strip()
            if name and subvolume:
                configs.append(SnapperConfig(name=name, subvolume=subvolume))

    return configs


def get_snapper_configs() -> List[SnapperConfig]:
    """Get snapper configurations.

    Returns:
        List of SnapperConfig objects
    """
    if not is_snapper_available():
        return []

    cmd = build_snapper_list_configs()
    returncode, output = run_command(cmd)
    if returncode != 0:
        return []

    return parse_snapper_list_configs(output)


def get_mount_point_for_partition(device_path: str) -> Optional[str]:
    """Get the mount point for a given partition device."""
    try:
        with open("/proc/mounts", "r") as f:
            for line in f:
                parts = line.split()
                if len(parts) >= 2:
                    device = parts[0]
                    mount_point = parts[1]
                    if device == device_path:
                        return mount_point
    except (IOError, OSError):
        pass
    return None


def find_btrfs_device_for_path(path: str) -> Optional[str]:
    """Find the btrfs device that contains the given path.

    This uses /proc/mounts to map mount points to devices.
    """
    # Get the device for the mount point from /proc/mounts
    try:
        with open("/proc/mounts", "r") as f:
            for line in f:
                parts = line.split()
                if len(parts) >= 3:
                    device = parts[0]
                    mount_point = parts[1]
                    fs_type = parts[2]
                    if fs_type == "btrfs" and mount_point == path:
                        return device
    except (IOError, OSError):
        pass

    return None


def get_snapper_managed_devices() -> Set[str]:
    """Get set of device paths that have snapper configurations.

    Returns:
        Set of device paths (e.g., '/dev/sda5') that are managed by snapper
    """
    managed_devices = set()

    configs = get_snapper_configs()

    for config in configs:
        # Find the device for this subvolume
        device = find_btrfs_device_for_path(config.subvolume)
        if device:
            managed_devices.add(device)

    return managed_devices


def get_snapper_config_for_mountpoint(mountpoint: str) -> Optional[str]:
    """Get the snapper config name for a given mount point.

    Returns:
        Config name (e.g., "home", "root") or None if not managed
    """
    configs = get_snapper_configs()
    for config in configs:
        if config.subvolume == mountpoint:
            return config.name
    return None


def get_snapper_mountpoint_to_config_map() -> Dict[str, str]:
    """Get a mapping of mount points to snapper config names.

    Returns:
        Dictionary mapping mount point to config name
    """
    configs = get_snapper_configs()
    return {config.subvolume: config.name for config in configs}


def get_snapper_managed_mount_points() -> Set[str]:
    """Get set of mount points that have snapper configurations.

    Returns:
        Set of mount points (e.g., '/home') that are managed by snapper
    """
    configs = get_snapper_configs()
    return {config.subvolume for config in configs}
