{ lib, pkgs, config, ...}:
let
  inherit (lib) mkOption mkEnableOption types mapAttrsToList;
  inherit (pkgs.pseudofile) dir symlink;
  inherit (lib.strings) toUpper;

  attrs = { options, applets } :
    let
      extraOptions = builtins.concatStringsSep "\n"
        (mapAttrsToList (n: v: "CONFIG_${toUpper n} ${toString v}") options);
      appletOptions = builtins.concatStringsSep "\n"
        (map (n: "CONFIG_${toUpper n} y") applets);
    in {
      enableMinimal = true;
      extraConfig = ''
        ${extraOptions}
        ${appletOptions}
      '';
    };
  cfg = config.programs.busybox;
  busybox = pkgs.busybox.override (attrs { inherit (cfg) applets options; });
  makeLinks = lib.attrsets.genAttrs
    cfg.applets
    (a: symlink "${busybox}/bin/busybox");
  minimalApplets = [
    # this is probably less minimal than it could be
    "arch" "ash" "base64" "basename" "bc" "brctl" "bunzip2" "bzcat"
    "bzip2" "cal" "cat" "chattr" "chgrp" "chmod" "chown" "chpst"
    "chroot" "clear" "cmp" "comm" "cp" "cpio" "cut" "date" "dd" "df"
    "dirname" "dmesg" "du" "echo" "egrep" "env" "expand" "expr"
    "false" "fdisk" "fgrep" "find" "free" "fuser" "grep" "gunzip"
    "gzip" "head" "hexdump" "hostname" "hwclock" "ifconfig" "ip"
    "ipaddr" "iplink" "ipneigh" "iproute" "iprule" "kill" "killall"
    "killall5" "less" "ln" "ls" "lsattr" "lsof" "md5sum" "mkdir"
    "mknod" "mktemp" "mount" "mv" "nc" "netstat" "nohup" "od" "pgrep"
    "pidof" "ping" "ping6" "pkill" "pmap" "printenv" "printf" "ps"
    "pwd" "readlink" "realpath" "reset" "rm" "rmdir" "route" "sed"
    "seq" "setsid" "sha1sum" "sha256sum" "sha512sum" "sleep" "sort"
    "stat" "strings" "stty" "su" "sum" "swapoff" "swapon" "sync"
    "tail" "tee" "test" "time" "touch" "tr" "traceroute" "traceroute6"
    "true" "truncate" "tty" "udhcpc" "umount" "uname"
    "unexpand" "uniq" "unlink" "unlzma" "unxz" "unzip" "uptime"
    "watch" "wc" "whoami" "xargs" "xxd" "xz" "xzcat" "yes" "zcat"
  ];
in {
  options = {
    programs.busybox = {
      applets =  mkOption {
        type = types.listOf types.str;
        default = [];
        example = ["sh" "getty" "login"];
      };
      options = mkOption {
        # mostly the values are y n or m, but sometimes
        # other strings are also used
        type = types.attrsOf types.nonEmptyStr;
        default =  { };
      };
    };
  };
  config = {
    programs.busybox = {
      applets = minimalApplets;
      options = {
        ASH_ECHO = "y";
        # ASH_OPTIMIZE_FOR_SIZE = "y";
        BASH_IS_NONE = "y";
        SH_IS_ASH = "y";
        ASH_BASH_COMPAT = "y";
        FEATURE_EDITING = "y"; # readline-ish command editing
        FEATURE_EDITING_HISTORY = "128";
        FEATURE_EDITING_MAX_LEN = "1024";
        FEATURE_TAB_COMPLETION = "y";
        FEATURE_EDITING_WINCH = "y";
        FEATURE_IPV6 = "y";
      };
    };
    filesystem = dir {
      bin = dir ({
        busybox = symlink "${busybox}/bin/busybox";
        sh = symlink "${busybox}/bin/busybox";
      } // makeLinks);
    };
  };
}