"""Memory-isolation check (MALWARE_ANALYSIS.md §5.7, 1 check).

- :func:`memory_no_balloon` — ``<memballoon model='none'/>``.
  The balloon driver lets the host reclaim guest memory;
  ambiguous threat model but a real attack surface (CVE-2017-7541
  was a balloon-driver bug). Disabling closes the surface.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from mgf.vm.core.security.isolation.checks._helpers import finding
from mgf.vm.core.security.isolation.types import (
    FixKind,
    IsolationCategory,
    IsolationFinding,
    isolation_check,
)

if TYPE_CHECKING:
    from mgf.vm.core.security.isolation.context import AnalysisContext


__all__ = ["memory_no_balloon"]


@isolation_check
def memory_no_balloon(ctx: AnalysisContext) -> IsolationFinding:
    """``<memballoon model='none'/>`` (or no balloon at all)."""
    balloons = ctx.find_devices("memballoon")
    enabled = [b for b in balloons if b.get("model") != "none"]
    return finding(
        fid="memory.no_balloon",
        title="Memory balloon disabled",
        category=IsolationCategory.ADVISORY,
        fix_kind=FixKind.AUTO_FIX,
        passing=not enabled,
        summary_pass=(
            "memballoon model='none' (or no balloon device)"
            if balloons
            else "no <memballoon> element"
        ),
        summary_fail=(
            f"{len(enabled)} memballoon(s) with model != 'none': "
            f"{[b.get('model', '?') for b in enabled]}"
        ),
        details={"models": [b.get("model", "?") for b in balloons]},
        fix_executor="memory.add_balloon_none",
    )
