{ lib ? lib, self, inputs, outputs, stateVersion, hmStateVersion , ... }: {
  deploy = {
    hostname, 
    system    ? "x86_64-linux", 
    username  ? "albert"
  }: {
    user = "root";
    sshUser = "${username}";
    hostname = "${hostname}";
    sshOpts = [ "-A" "-q"];

    profiles = {
      system.path = inputs.deploy-rs.lib.${system}.activate.nixos self.nixosConfigurations.${hostname};
      home-manager.path = inputs.deploy-rs.lib.${system}.activate.home-manager self.homeConfigurations."${username}@${hostname}";
      home-manager.user = "${username}";
    };
  };

  # Helper function for generating home-manager configs
  mkHome = { 
    hostname, 
    username ? "albert",
    desktop  ? null, 
    system   ? "x86_64-linux", 
    theme    ? "default",
    type     ? "default",
  }: inputs.home-manager.lib.homeManagerConfiguration {
    pkgs = inputs.nixpkgs.legacyPackages.${system};
    extraSpecialArgs = { inherit inputs outputs desktop hostname system username hmStateVersion theme; };
    modules = [ ../home-manager/${type}.nix ];
  };

  mkContainer = { 
    hostname, 
    username  ? "albert",
    desktop   ? null, 
    system    ? "x86_64-linux", 
    theme     ? "default",
    # type      ? "default",
    repo      ? "nixpkgs",
    unfree    ? false,
    ip        ? null,
    ephemeral ? false,
    deployment_type ? "containers", # Currently used to change where secrets are searched for 
    pkgs          ? let packages = (import ./packages.nix { inherit inputs repo system unfree; }); in packages.pkgs,
    pkgs-unstable ? let packages = (import ./packages.nix { inherit inputs repo system unfree; }); in packages.pkgs-unstable,
  }: { 
    bindMounts       = lib.mkMerge [ 
      ( import ../nixos/containers/mounts.nix )
      ( import ../nixos/containers/${hostname}/mounts.nix )
    ];
    ephemeral        = ephemeral;
    autoStart        = true;
    privateNetwork   = true;
    hostBridge       = "nix-br0";
    localAddress     = "192.168.2.${ip}";
    restartIfChanged = true;
    enableTun        = true;
    specialArgs = { inherit pkgs-unstable hostname username desktop theme system repo unfree stateVersion ip deployment_type; };
    config = { hostname, username, desktop, theme, system, stateVersion, ... }: {
      nixpkgs.pkgs = pkgs;

      imports = [ 
        ../nixos/containers
        inputs.sops-nix.nixosModules.sops
        inputs.home-manager.nixosModules.home-manager {
          home-manager.extraSpecialArgs  = { inherit inputs outputs desktop hostname username hmStateVersion stateVersion system theme ; };
          home-manager.users."${username}" = import ../home-manager;
        }
      ];
    };
  };

  # Helper function for generating host configs
  mkDeck = { 
    hostname, 
    username  ? "albert",
    desktop   ? null, 
    gpu       ? null, 
    system    ? "x86_64-linux", 
    theme     ? "default",
    type      ? "default",
    repo      ? "nixpkgs-unstable",
    unfree    ? true,
    deployment_type ? "hosts",
  }: inputs.${repo}.lib.nixosSystem { 
    specialArgs = { 
      inherit inputs outputs desktop hostname username hmStateVersion stateVersion gpu system theme self deployment_type;
      pkgs-unstable = let packages = (import ./packages.nix { inherit inputs repo system unfree; }); in packages.pkgs-unstable;
    };

    modules = [
      # Types are 'default', 'small', and 'minimal'
      ../nixos/${type}.nix
      inputs.sops-nix.nixosModules.sops
      inputs.lanzaboote.nixosModules.lanzaboote
    ];
  };


  # Helper function for generating host configs
  mkHost = { 
    hostname, 
    username  ? "albert",
    desktop   ? null, 
    gpu       ? null, 
    system    ? "x86_64-linux", 
    theme     ? "default",
    type      ? "default",
    repo      ? "nixpkgs",
    deployment_type ? "hosts",
    unfree    ? false
  }: inputs.${repo}.lib.nixosSystem { 
    specialArgs = { 
      inherit inputs outputs desktop hostname username hmStateVersion stateVersion gpu system theme self deployment_type;
      # Choose whether to pull from stable or unstable 
      pkgs          = let packages = (import ./packages.nix { inherit inputs repo system unfree; }); in packages.pkgs;
      pkgs-unstable = let packages = (import ./packages.nix { inherit inputs repo system unfree; }); in packages.pkgs-unstable;
    };

    modules = [
      # Types are 'default', 'small', and 'minimal'
      ../nixos/${type}.nix
      inputs.sops-nix.nixosModules.sops
      inputs.lanzaboote.nixosModules.lanzaboote
    ];
  };

  # Combines mkHost and mkHome for image building
  mkImage = {
    hostname  , 
    username  ? "albert",
    desktop   ? null, 
    system    ? "x86_64-linux",
    gpu       ? null, 
    theme     ? "default",
    repo      ? "nixpkgs",
    unfree    ? false,
    format
  }: inputs.nixos-generators.nixosGenerate {
    specialArgs = { 
      inherit inputs outputs desktop hostname username stateVersion hmStateVersion gpu system theme format; 
      # Choose whether to pull from stable or unstable 
      pkgs          = let packages = (import ./packages.nix { inherit inputs repo system unfree; }); in packages.pkgs;
      pkgs-unstable = let packages = (import ./packages.nix { inherit inputs repo system unfree; }); in packages.pkgs-unstable;
    };
    system = system;
    format = format;

    modules = [
      ../nixos
      ../nixos/common/modules/installer.nix
      "${inputs.nixpkgs}/nixos/modules/profiles/all-hardware.nix"
      inputs.sops-nix.nixosModules.sops
      inputs.lanzaboote.nixosModules.lanzaboote
      inputs.home-manager.nixosModules.home-manager {
        home-manager.extraSpecialArgs  = { inherit inputs outputs desktop hostname username hmStateVersion stateVersion gpu system theme format; };
        home-manager.users."${username}" = import ../home-manager;
      }
    ];
  };

  # Small version
  mkMinImage = {
    hostname  , 
    username  ? "albert",
    desktop   ? null, 
    system    ? "x86_64-linux",
    gpu       ? null, 
    theme     ? "default",
    format
  }: inputs.nixos-generators.nixosGenerate {
    specialArgs = { inherit inputs outputs desktop hostname username stateVersion hmStateVersion gpu system theme format; };
    system = system;
    format = format;

    modules = [
      ../nixos/minimal.nix
      ../nixos/common/modules/installer.nix
      inputs.sops-nix.nixosModules.sops
    ];
  };

  forAllSystems = inputs.nixpkgs.lib.genAttrs [
    "aarch64-linux"
    "x86_64-linux"
  ];
}