{ pkgs
, lib
, config
, ... }: with lib; let
  cfg = config.global.io;
  gui = with config.global.gpu; enable && session;
in {
  options.global.io = {
    betaflight = mkEnableOption "betaflight udev rules" // { default = gui; };
    bluetooth = mkEnableOption "bluetooth daemons and state persistence" // { default = gui; };
    audio = mkEnableOption "pulseaudio server configuration" // { default = gui; };
    coredump = mkEnableOption "save coredumps handled by systemd";
  };

  config = {
    services.udev.extraRules = ''
      # ignore zvols
      KERNEL=="zd*", ENV{UDISKS_IGNORE}="1"
    '' + (if cfg.betaflight then ''
      # DFU (Internal bootloader for STM32 and AT32 MCUs)
      SUBSYSTEM=="usb", ATTRS{idVendor}=="2e3c", ATTRS{idProduct}=="df11", MODE="0664", GROUP="dialout"
      SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE="0664", GROUP="dialout"
    '' else "");

    networking.networkmanager.enable = mkDefault true;
    networking.hosts = {
      "10.5.14.0" = [ "codec" ];
      "10.5.14.1" = [ "redir" ];
      "10.5.14.2" = [ "compat" ];

      "192.168.123.1" = [ "netvm" ];
    };
    networking.firewall.logRefusedConnections = true;
    hardware.bluetooth.enable = mkDefault cfg.bluetooth;

    # rtkit is optional but recommended
    security.rtkit.enable = cfg.audio;
    services.pipewire = mkIf cfg.audio {
      enable = true;
      alsa.enable = true;
      alsa.support32Bit = true;
      pulse.enable = true;
      jack.enable = true;
    };

    security.pam.loginLimits = mkIf (!cfg.coredump) (singleton { domain = "*"; item = "core"; type = "hard"; value = "0"; });
    systemd.coredump.extraConfig = mkIf (!cfg.coredump) "Storage=none";

    environment.persistence."/nix/persist/fhs".directories = [
      "/var/log"
      "/var/lib/nixos"
      "/var/lib/systemd/backlight"
    ] ++
    optional config.networking.networkmanager.enable "/etc/NetworkManager/system-connections" ++
    optional cfg.bluetooth "/var/lib/bluetooth" ++
    optional cfg.coredump "/var/lib/systemd/coredump";
    environment.persistence."/nix/persist/fhs".hideMounts = true;

    users.home.persist.directories = [ ] ++
    optional cfg.audio ".local/state/wireplumber";
  };
}