{
  description = "GKleen's flakey nixos configuration";

  nixConfig = {
    extra-substituters = [
      "https://nix-community.cachix.org"
      "https://niri.cachix.org"
    ];
    extra-trusted-public-keys = [
      "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
      "niri.cachix.org-1:Wv0OmO7PsuocRKzfDoJ3mulSl7Z6oezYhGhR+3W2964="
    ];
  };

  inputs = {
    nixpkgs = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "nixos-unstable";
    };
    nixpkgs-pgbackrest = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "23.05";
    };
    nixpkgs-stable = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "24.05";
    };
    nixpkgs-eostre = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "23.11";
    };
    home-manager = {
      type = "github";
      # owner = "nix-community";
      # repo = "home-manager";
      # ref = "master";
      owner = "gkleen";
      repo = "home-manager";
      ref = "nixos-late-start";
      inputs = {
        nixpkgs.follows = "nixpkgs";
      };
    };
    home-manager-eostre = {
      type = "github";
      owner = "gkleen";
      repo = "home-manager";
      ref = "nixos-late-start-23.11";
      inputs = {
        nixpkgs.follows = "nixpkgs-eostre";
      };
    };
    sops-nix = {
      type = "github";
      owner = "Mic92";
      repo = "sops-nix";
      ref = "master";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    deploy-rs = {
      type = "github";
      owner = "serokell";
      repo = "deploy-rs";
      ref = "master";
      inputs = {
        nixpkgs.follows = "nixpkgs";
        utils.follows = "flake-utils";
        flake-compat.follows = "flake-compat";
      };
    };
    nvfetcher = {
      type = "github";
      owner = "berberman";
      repo = "nvfetcher";
      ref = "master";
      inputs = {
        nixpkgs.follows = "nixpkgs";
        flake-utils.follows = "flake-utils";
        flake-compat.follows = "flake-compat";
      };
    };
    flake-compat = {
      type = "github";
      owner = "edolstra";
      repo = "flake-compat";
      ref = "master";
      flake = false;
    };
    flake-utils = {
      type = "github";
      owner = "numtide";
      repo = "flake-utils";
      ref = "main";
    };
    flake-registry = {
      type = "github";
      owner = "NixOS";
      repo = "flake-registry";
      flake = false;
    };
    nix-index-database = {
      type = "github";
      owner = "Mic92";
      repo = "nix-index-database";
      ref = "main";
      inputs = {
        nixpkgs.follows = "nixpkgs";
      };
    };
    poetry2nix = {
      type = "github";
      owner = "nix-community";
      repo = "poetry2nix";
      ref = "master";
      inputs = {
        flake-utils.follows = "flake-utils";
        nixpkgs.follows = "nixpkgs";
      };
    };

    ca-util = {
      type = "gitlab";
      owner = "gkleen";
      repo = "ca";
      ref = "v3.1.3";
      inputs = {
        nixpkgs.follows = "nixpkgs";
        poetry2nix.follows = "poetry2nix";
      };
    };
    backup-utils = {
      type = "gitlab";
      owner = "gkleen";
      repo = "backup-utils";
      ref = "v0.1.6";
      inputs = {
        nixpkgs.follows = "nixpkgs";
        poetry2nix.follows = "poetry2nix";
      };
    };
    prometheus-borg-exporter = {
      type = "gitlab";
      owner = "gkleen";
      repo = "prometheus-borg-exporter";
      ref = "main";
      inputs = {
        nixpkgs.follows = "nixpkgs";
        poetry2nix.follows = "poetry2nix";
      };
    };
    nixos-hardware = {
      type = "github";
      owner = "NixOS";
      repo = "nixos-hardware";
      ref = "master";
    };
    impermanence = {
      type = "github";
      owner = "nix-community";
      repo = "impermanence";
      ref = "master";
    };
    waybar = {
      type = "github";
      owner = "gkleen";
      repo = "Waybar";
      ref = "feat/niri-workspaces-hide";
      inputs = {
        nixpkgs.follows = "nixpkgs";
        flake-compat.follows = "flake-compat";
      };
    };
    nixVirt = {
      type = "github";
      owner = "AshleyYakeley";
      repo = "NixVirt";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    niri-flake = {
      type = "github";
      owner = "sodiboo";
      repo = "niri-flake";
      ref = "main";
      inputs = {
        nixpkgs.follows = "nixpkgs";
        niri-unstable.url = "github:gkleen/niri";
      };
    };
  };

  outputs = { self, nixpkgs, home-manager, sops-nix, deploy-rs, nvfetcher, niri-flake, ... }@inputs:
    let
      inherit (builtins) attrNames attrValues elemAt toJSON isNull pathExists;
      inherit (nixpkgs) lib;
      utils = import ./utils { inherit lib; };
      inherit (utils) nixImport overrideModule;
      inherit (lib) mkIf splitString filterAttrs listToAttrs mapAttrsToList nameValuePair concatMap composeManyExtensions mapAttrs mapAttrs' recursiveUpdate genAttrs unique elem optionalAttrs isDerivation concatLists concatStringsSep fix filter makeOverridable foldr;
      inherit (lib.strings) escapeNixString hasSuffix;

      accountUserName = accountName:
        let
          accountName' = splitString "@" accountName;
        in elemAt accountName' 0;
      accountHostName = accountName:
        let
          accountName' = splitString "@" accountName;
        in elemAt accountName' 1;

      mkSources = pkgs: optionalAttrs (pathExists _sources/generated.nix) { sources = pkgs.callPackage _sources/generated.nix {}; };

      mkOverlay = path: final: prev: import path ({ inherit final; inherit prev; flakeInputs = inputs; flake = self; } // mkSources prev);

      mkNixosConfiguration = addProfiles: dir: path: hostName:
        let inherit ((inputs."nixpkgs-${hostName}" or inputs.nixpkgs).lib) nixosSystem;
        in nixosSystem rec {
          specialArgs = {
            flake = self;
            flakeInputs = inputs;
            path = ./.;
            home-manager = inputs.${if inputs ? "home-manager-${hostName}" then "home-manager-${hostName}" else "home-manager"};
          };
          modules =
            let
              defaultProfiles = with self.nixosModules.systemProfiles;
                [ core
                ];

              local = dir + "/${path}";
              argsModule = { pkgs, ... }: {
                _module.args = {
                  customUtils = utils;
                  inherit hostName;
                } // mkSources pkgs;
              };
              accountModules = attrValues (filterAttrs accountMatchesHost self.nixosModules.accounts);
              accountMatchesHost = n: _v: accountHostName n == hostName;
            in attrValues (filterAttrs (n: _v: !(elem n ["systemProfiles" "users" "userProfiles" "accounts"])) self.nixosModules) ++ [ argsModule ] ++ defaultProfiles ++ addProfiles ++ [ local ] ++ accountModules;
        };

      mkSystemProfile = dir: path: profileName: {
        imports = [ (dir + "/${path}") ];
        config = {
          system.profiles = [profileName];
        };
      };

      defaultUserProfiles = userName: with self.nixosModules.userProfiles.${userName};
        [ core
        ];

      mkUserModule = dir: path: userName:
        overrideModule (import (dir + "/${path}"))
                       (inputs: inputs // { inherit userName; })
                       (outputs: { _file = dir + "/${path}"; }
                              // outputs
                              // { imports = defaultUserProfiles userName ++ (outputs.imports or []); });

      mkUserProfile = userName: dir: path: profileName:
        let
          profileModule = overrideModule (import (dir + "/${path}"))
                                         (inputs: inputs // { inherit userName; })
                                         (outputs: { _file = dir + "/${path}"; }
                                                // outputs);
        in {
          imports = [profileModule];
          config = {
            users.users.${userName}.profiles = [profileName];
          };
        };

      mkAccountModule = dir: path: accountName:
        let
          userName = accountUserName accountName;
          hostName = accountHostName accountName;
        in overrideModule
             (import (dir + "/${path}"))
             (inputs: inputs // { inherit userName hostName; })
             (outputs: { _file = dir + "/${path}"; }
                      // outputs
                      // { imports = [self.nixosModules.users.${userName} or ({...}: { imports = defaultUserProfiles userName; })] ++ (outputs.imports or []); });

      systemsSelector = "x86_64-linux";
      systems = filter (system: !(isNull (builtins.match systemsSelector system))) nixpkgs.lib.systems.flakeExposed;
      # systems =
      #   let
      #     disallowedSystems = ["armv5tel-linux" "armv6l-linux"];
      #   in filter (system: !(elem system disallowedSystems)) nixpkgs.lib.systems.flakeExposed;
      nixpkgsPackages = localSystem: (makeOverridable (import (nixpkgs.outPath + "/pkgs/top-level"))) { inherit localSystem; };
      forAllSystems = f: mapAttrs f (genAttrs systems nixpkgsPackages);
      forAllUsers = genAttrs (unique (map accountUserName (attrNames self.nixosModules.accounts)));

      activateNixosConfigurations = forAllSystems (system: _pkgs: filterAttrs (_n: v: v != null) (mapAttrs' (hostName: nixosConfig: nameValuePair "${hostName}-activate" (if system == nixosConfig.config.nixpkgs.system then { type = "app"; program = "${nixosConfig.config.system.build.toplevel}/bin/switch-to-configuration"; } else null)) self.nixosConfigurations));
      startVMs = forAllSystems (system: pkgs: mapAttrs' (hostName: nixosConfig: nameValuePair "run-${hostName}-vm" { type = "app"; program = "${nixosConfig.config.system.build.vm}/bin/run-${hostName}-vm"; }) (nixImport rec { dir = ./hosts; _import = mkNixosConfiguration [ { config.virtualisation.host.pkgs = pkgs; } ] dir; }));
      activateHomeManagerConfigurations = forAllSystems (system: _pkgs: filterAttrs (_n: v: v != null) (listToAttrs (concatLists (mapAttrsToList (hostName: nixosConfig: mapAttrsToList (userName: userCfg: nameValuePair "${userName}@${hostName}-activate" (if system == nixosConfig.config.nixpkgs.system then { type = "app"; program = "${userCfg.home.activationPackage}/activate"; } else null)) nixosConfig.config.home-manager.users) self.nixosConfigurations))));
      installerShells = system: pkgs: mapAttrs (installerName: config: pkgs.callPackage ./installer/shell.nix {
        inherit system installerName config;
      }) (filterAttrs (n: _v: hasSuffix "-netboot" n) installerNixosConfigurations);

      overlayPaths = nixImport rec { dir = ./overlays; _import = (path: _name: dir + "/${path}"); };

      installerProfiles = nixImport rec {
        dir = ./installer-profiles;
        _import = path: name: mkSystemProfile dir path "installer-${name}";
      };

      installerConfig = if pathExists ./installer.nix then "installer.nix" else (if pathExists ./installer then "installer" else null);
      mkInstallerForSystem = system: (lib.systems.elaborate system).isLinux;
      installers =
        let mkInstallers = system: mapAttrs (mkInstaller system) installerProfiles;
            mkInstaller = system: name: profile: mkNixosConfiguration [profile { config.nixpkgs.system = system; }] ./. installerConfig "installer";
        in forAllSystems (system: _systemPkgs: optionalAttrs (!(isNull installerConfig) && mkInstallerForSystem system) (mkInstallers system));
      installerNixosConfigurations = listToAttrs (concatLists (mapAttrsToList (system: mapAttrsToList (profile: config: nameValuePair ("installer-${system}-${profile}") config)) installers));

      # packages = forAllSystems (system: systemPkgs: composeManyExtensions (attrValues self.overlays) self.legacyPackages.${system} systemPkgs);

      activateHomeManager = system: base: (deploy-rs.lib.${system}.activate.custom // { dryActivate = "DRY_RUN=1 $PROFILE/activate"; }) base.activationPackage "$PROFILE/activate";
    in
      {
        nixosModules =
          let modulesAttrs = nixImport { dir = ./modules; };
              systemProfiles = nixImport rec { dir = ./system-profiles; _import = mkSystemProfile dir; };
              users = nixImport rec { dir = ./users; _import = mkUserModule dir; };
              userProfiles = forAllUsers (userName: nixImport rec { dir = ./user-profiles; _import = mkUserProfile userName dir; });
              accounts = recursiveUpdate rootAccounts (nixImport rec { dir = ./accounts; _import = mkAccountModule dir; });
              rootAccounts = mapAttrs' (hostName: _value: nameValuePair "root@${hostName}" ({...}: { imports = [ self.nixosModules.users.root or ({...}: { imports = defaultUserProfiles "root"; }) ]; })) self.nixosConfigurations;
          in modulesAttrs // { inherit systemProfiles users userProfiles accounts; };
        nixosConfigurations = installerNixosConfigurations // nixImport rec { dir = ./hosts; _import = mkNixosConfiguration [] dir; };

        homeModules = nixImport rec { dir = ./home-modules; };
        homeConfigurations = listToAttrs (concatLists (mapAttrsToList (hostname: nixosConfig: mapAttrsToList (username: nameValuePair "${username}@${hostname}") nixosConfig.config.home-manager.users) self.nixosConfigurations));

        overlays = mapAttrs (_name: path: mkOverlay path) overlayPaths;

        packages = forAllSystems (system: systemPkgs: nixImport rec { dir = ./tools; _import = _path: name: import "${toString dir}/${name}" ({ inherit system; } // inputs); });

        # packages = mapAttrs (_name: filterAttrs (_name: isDerivation)) packages;
        # packages' = mapAttrs (_name: filterAttrs (_name: value: !(isDerivation value))) packages;

        legacyPackages = forAllSystems (system: systemPkgs: systemPkgs.override { overlays = attrValues self.overlays; });

        apps = foldr recursiveUpdate {} [startVMs activateNixosConfigurations activateHomeManagerConfigurations];

        devShells = forAllSystems (system: systemPkgs: { default = import ./shell.nix ({ inherit system; } // inputs); } // installerShells system systemPkgs);

        templates.default = {
          path = ./.;
          description = "GKleen's flakey nixos configuration";
        };

        deploy.nodes = let
          defaults = mapAttrs (hostname: _: {
            inherit hostname;
            sshUser = "root";
            sshOpts = [ "-S" "none" ];

            profilesOrder = ["system"]; # system first
            profiles = {
              system = {
                path = deploy-rs.lib.${self.nixosConfigurations.${hostname}.config.nixpkgs.system}.activate.nixos self.nixosConfigurations.${hostname};
              };
            }; # // (mapAttrs (_user: usercfg: {
            #   user = usercfg.home.username;
            #   path = activateHomeManager (self.nixosConfigurations.${hostname}.config.nixpkgs.system) usercfg.home;
            # }) self.nixosConfigurations.${hostname}.config.home-manager.users);
          }) (nixImport { dir = ./hosts; _import = (_path: name: name); });
          overrides = if pathExists ./deploy then nixImport { dir = ./deploy; _import = path: _name: import (./deploy + "/${path}") inputs; } else {};
          filterEnabled = attrs: mapAttrs (_n: v: filterAttrs (n: _v: n != "enabled") v) (filterAttrs (_n: v: v.enabled or true) attrs);
        in mapAttrs (_n: v: if v ? "profiles" then v // { profiles = filterEnabled v.profiles; } else v) (filterEnabled (recursiveUpdate defaults overrides));

        checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib;
      };
}