"""AUR-Scanner: paru clone-cache (~/.cache/paru/clone/<pkg>/).

Die installierten AUR-Pakete tauchen via `pacman -Qq` auf (AUR ist nur
ein Build-System, die Pakete landen ganz normal in der lokalen DB).
Ein Clone in `~/.cache/paru/` ohne entsprechendes installiertes Paket
ist also verwaist.
"""
from __future__ import annotations

import os
import subprocess
from pathlib import Path

from taninux.maintain.scanners._util import dir_size, last_access_days
from taninux.maintain.types import Category, Classification, Finding


PARU_CACHE = Path.home() / ".cache" / "paru"


def _pacman_installed() -> set[str]:
    try:
        r = subprocess.run(
            ["pacman", "-Qq"],
            capture_output=True, text=True, check=False, timeout=10,
        )
    except (FileNotFoundError, subprocess.TimeoutExpired):
        return set()
    return {l.strip() for l in r.stdout.splitlines() if l.strip()}


class AurCacheScanner:
    name = "aur-cache"

    def scan(self) -> list[Finding]:
        clone_root = PARU_CACHE / "clone"
        if not clone_root.is_dir():
            return []
        installed = _pacman_installed()

        findings: list[Finding] = []
        try:
            entries = list(os.scandir(clone_root))
        except (OSError, PermissionError):
            return []

        for entry in entries:
            try:
                if not entry.is_dir(follow_symlinks=False):
                    continue
            except OSError:
                continue
            pkg = entry.name
            path = Path(entry.path)
            size = dir_size(path)
            days = last_access_days(path)
            is_installed = pkg in installed

            if not is_installed:
                cls = Classification.SAFE
                reason = f"AUR-Paket {pkg} nicht installiert — Clone verwaist"
            elif days is not None and days > 180:
                cls = Classification.LIKELY_ORPHAN
                reason = f"AUR-Clone von {pkg} seit {days}d unverändert"
            else:
                cls = Classification.ACTIVE
                reason = f"AUR-Clone von {pkg} — installiert, möglicher Rebuild-Source"

            # Active wird in der Übersicht meist nicht gesized
            if cls == Classification.ACTIVE:
                size_to_show = 0
            else:
                size_to_show = size

            findings.append(Finding(
                path=path,
                category=Category.AUR,
                classification=cls,
                size_bytes=size_to_show,
                last_access_days=days,
                reason=reason,
                matched_package=pkg,
                extra={"kind": "paru-clone", "pkg": pkg},
            ))
        findings.sort(key=lambda f: f.sort_key)
        return findings
