{
  lib,
  config,
  pkgs,
  ...
}:
let
  inherit (lib)
    mkIf
    mkEnableOption
    mkOption
    concatMapStrings
    attrsToList
    ;
  inherit (lib.types)
    str
    attrsOf
    listOf
    ;
  inherit (lib.my) getExe;

  cfg = config.modules.services.udev;

  bindUsb = pkgs.writers.writeBashBin "mount-usb" {
    makeWrapperArgs = [
      "--prefix"
      "PATH"
      ":"
      "${lib.makeBinPath [ pkgs.libvirt ]}"
    ];
  } ./hotplug.sh;

  mkUdevHotplug = domain: product: ''
    ENV{PRODUCT}=="${product}", \
            SUBSYSTEMS=="usb", \
            RUN+="${getExe bindUsb} ${domain}"
  '';
in
{

  options.modules.services.udev = {
    enable = mkEnableOption "";
    libvirtHotplug = mkOption {
      default = [ ];
      type = attrsOf (listOf str);
      description = ''
        The udev rules used to match USB devices, all normal udev patterns are usable.
      '';
      example = ''[ "303a/1001/*" ]'';
    };
  };

  config = mkIf cfg.enable {
    services.udev = {
      enable = true;
      packages = [
        (pkgs.writeTextFile {
          name = "udev-vm-hotplug-rules";
          text = concatMapStrings (
            { name, value }: concatMapStrings (product: mkUdevHotplug name product) value
          ) (attrsToList cfg.libvirtHotplug);
          destination = "/etc/udev/rules.d/99-hotplug.rules";
        })
      ];
    };
  };
}