{ pkgs
, lib
, config
, ... }: with lib; let
  cfg = config.users;
in {
  options.users = {
    profiles = mkOption {
      type = with types; attrsOf (submodule {
        options = {
          uid = mkOption {
            type = with types; nullOr int;
            default = null;
            description = "uid passthrough to base user configuration";
          };
          description = mkOption {
            type = with types; nullOr str;
            default = null;
            description = "description passthrough to base user configuration";
          };
          admin = mkOption {
            type = with types; bool;
            default = false;
            description = "add user to privileged groups";
          };
          sshLogin = mkOption {
            type = with types; bool;
            default = false;
            description = "enable ssh authorized keys for user";
          };
          picture = mkOption {
            type = with types; nullOr path;
            default = null;
            description = "path to user profile picture";
          };
        };
      });
      description = "preconfigured users with profile options";
    };

    adminGroups = mkOption {
      type = with types; listOf str;
      description = "groups to add privileged users to";
    };

    homeModules = mkOption {
      type = with types; listOf anything;
      description = "home manager modules imported into every profile";
    };

    home = {
      size = mkOption {
        type = with types; str;
        default = "1G";
        description = "default home tmpfs size, mounted to prevent accidentally filling up root";
      };
      persist = {
        files = mkOption {
          type = with types; listOf (oneOf [ str (attrsOf str) ]);
          default = [ ];
        };
        directories = mkOption {
          type = with types; listOf (oneOf [ str (attrsOf str) ]);
          default = [ ];
        };
      };
    };
  };

  config = {
    users = {
      users = mapAttrs (name: opts: {
        inherit (opts) uid;
        description = with opts; mkIf (description != null) description;
        extraGroups = [ "dialout" ] ++ optionals opts.admin cfg.adminGroups;
        openssh.authorizedKeys.keys = mkIf (opts.sshLogin && config.services.openssh.enable)
        config.global.auth.openssh.publicKeys;
        hashedPasswordFile = "/nix/persist/shadow/${name}";
        shell = pkgs.zsh;
        isNormalUser = mkIf (name != "root") true;
      }) cfg.profiles;

      mutableUsers = false;

      # base groups
      adminGroups = [
        "wheel" "kvm"
        "systemd-journal"
      ];

      # base home modules in current directory
      homeModules = pipe ./. [
        builtins.readDir
        (filterAttrs (n: ty: ty == "directory" && builtins.pathExists ./${n}/home.nix))
        (mapAttrsToList (n: _: ./${n}/home.nix))
      ] ++ [ {
        options.passthrough = mkOption {
          type = with types; attrsOf anything;
          description = "passthrough values from nixos configuration";
        };
      } ];

      # basic persistence
      home.persist = {
        directories = [
          "src"
          { directory = ".gnupg"; mode = "0700"; }
          { directory = ".ssh"; mode = "0700"; }
          { directory = ".local/share/keyrings"; mode = "0700"; }
        ];
      };
    };

    # mount tmpfs on each user's home directory with appropriate ownership
    fileSystems = mapAttrs'
    (name: opts: nameValuePair
    # nixpkgs quirk: accessing user configuration here causes infinite recursion
    # this workaround ensures proper home directory path unless overridden elsewhere
    (if name != "root" then "/home/${name}" else "/root") {
      device = "homefs";
      fsType = "tmpfs";
      options = [ "size=${cfg.home.size}"
      "uid=${builtins.toString opts.uid}"
      "gid=${builtins.toString cfg.groups.${cfg.users.${name}.group}.gid}"
      "mode=700" ];

      # impermanence sets permissions before filesystems are mounted
      # this mounts filesystem in initrd therefore working around that bug
      neededForBoot = true;
    }) cfg.profiles;

    global.fs.zfs.mountpoints = mapAttrs'
    (name: opts: nameValuePair
    "/nix/persist/home/${name}"
    "home/${name}")
    (filterAttrs (n: _: n != "root") config.users.profiles);

    home-manager.users = mapAttrs (name: opts: {
      imports = cfg.homeModules;
      home.file.".face" = mkIf (opts.picture != null) {
        source = opts.picture;
      };
      home.stateVersion = "23.11";
    }) cfg.profiles;

    # set up standard persistence for users
    # this is registered internally for each software's configuration
    environment.persistence."/nix/persist" = {
      users = (mapAttrs (name: _: cfg.home.persist // {
        # root workaround, ugly but necessary
        # cannot get it properly for the same reason
        # mentioned above in fileSystems
        home = mkIf (name == "root") "/root";
      }) cfg.profiles);

      hideMounts = true;
    };

    # enable passwordless sudo
    security.sudo.wheelNeedsPassword = false;
  };

  # this is for home components that need to extend nixos
  imports = pipe ./. [
    builtins.readDir
    (filterAttrs (n: ty: ty == "directory" && builtins.pathExists ./${n}/nixos.nix))
    (mapAttrsToList (n: _: ./${n}/nixos.nix))
  ];
}
