# Memory-pressure protection: keep the desktop alive when RAM runs out.
#
# A workstation that compiles from source WILL exhaust memory eventually —
# a big `nix build`, a runaway eval, a browser tab. The kernel's own OOM
# killer acts only after the system has thrashed itself unresponsive
# (often minutes of frozen desktop) and then picks by badness score,
# which can land on the compositor.
#
# earlyoom over systemd-oomd — a deliberate choice: oomd kills whole
# cgroups, and a Hyprland session runs as ONE scope (nothing spawns
# per-app systemd scopes here, unlike GNOME), so under pressure oomd
# would take out the entire desktop to save it. earlyoom kills a single
# process (highest oom_score ≈ the hog) BEFORE the thrash point — "kill
# the build step, keep the session". nixpkgs default-enables oomd in an
# inert state (no slices monitored); it's disabled outright below so
# there is exactly one owner of the OOM story.
{ lib, ... }:

{
  services.earlyoom = {
    enable = lib.mkDefault true;

    # Desktop toast when something is killed (relayed via
    # systembus-notify), so a vanished build/tab is explained rather
    # than mysterious.
    enableNotifications = lib.mkDefault true;

    # Never pick the session plumbing: losing the compositor or the lock
    # screen IS the outage this module exists to prevent (and killing a
    # Wayland session-lock client trips its go-to-a-tty failsafe). No
    # --prefer tuning: highest-memory selection already targets the hog.
    # Matched unanchored — NixOS wrappers rename comm to ".foo-wrapped".
    extraArgs = lib.mkDefault [
      "--avoid"
      "(Hyprland|hyprlock|greetd|waybar|pipewire|wireplumber|Xwayland|nix-daemon|systemd)"
    ];
  };

  # One owner (see header): oomd ships default-on but inert; make the
  # earlyoom choice explicit and total.
  systemd.oomd.enable = lib.mkDefault false;
}
