# This is just a library intended solely for this flake.
# It is expected to use the nixpkgs library with `lib/default.nix`.
{ lib }:

rec {
  mapHomeManagerUser = user: settings:
    let
      homeDirectory = "/home/${user}";
      defaultUserConfig = {
        extraGroups = [ "wheel" ];
        createHome = true;
        home = homeDirectory;
      };
      # TODO: Effectively override the option.
      # We assume all users set with this module are normal users.
      absoluteOverrides = { isNormalUser = true; };
    in
    {
      home-manager.users."${user}" = { ... }: {
        imports = [ (getUser "home-manager" user) ];
      };
      users.users."${user}" = defaultUserConfig // settings // absoluteOverrides;
    };

  getSecret = path: ../secrets/${path};

  getUsers = type: users:
    let
      userModules = lib.filesToAttr ../users/${type};
      invalidUsernames = [ "config" "modules" ];

      users' = lib.filterAttrs (n: _: !lib.elem n invalidUsernames && lib.elem n users) userModules;
      userList = lib.attrNames users';

      nonExistentUsers = lib.filter (name: !lib.elem name userList) users;
    in
    lib.trivial.throwIfNot ((lib.length nonExistentUsers) == 0)
      "there are no users ${lib.concatMapStringsSep ", " (u: "'${u}'") nonExistentUsers} from ${type}"
      (r: r)
      users';

  getUser = type: user:
    lib.getAttr user (getUsers type [ user ]);

  # Import modules with a set blocklist.
  importModules = attrs:
    let
      blocklist = [
        # The modules under this attribute are often incomplete and needing
        # very specific requirements that is 99% going to be absent from the
        # outside so we're not going to export it.
        "tasks"

        # Profiles are often specific to this project so there's not much point
        # in exporting these.
        "profiles"
      ];
    in
    lib.filterAttrs (n: v: !lib.elem n blocklist) (lib.mapAttrsRecursive (_: path: import path) attrs);
}