{
  description = "NixOS configuration with flakes";
  outputs = {
    alejandra,
    darwin,
    darwin-master,
    disko,
    endless-sky,
    flake-compat,
    flake-utils,
    helix,
    home-manager,
    home-manager-master,
    lix-module,
    nil,
    nix-ld,
    nixos-hardware,
    nixpkgs-master,
    nixpkgs-nixos-unstable,
    nixpkgs-rust-analyzer,
    nixpkgs-stable,
    nur,
    resilio3,
    self,
    sops,
  } @ inputs: let
    mkServer = pkgs: system: hostname:
      pkgs.lib.nixosSystem {
        inherit system;
        modules = [
          (./. + "/nixos/boxes/${hostname}")
          (import ./nixos/server-common.nix)
          sops.nixosModules.sops
          disko.nixosModules.disko
        ];
        specialArgs = {inherit inputs system;};
      };
    mkPrivateServer = pkgs: system: hostname:
      pkgs.lib.nixosSystem {
        inherit system;
        modules = [
          (import ./nixos/options.nix)
          (./. + "/nixos/boxes/${hostname}")
          (import ./nixos/server-common.nix)
          sops.nixosModules.sops
          disko.nixosModules.disko
          home-manager.nixosModules.home-manager
          {
            home-manager = {
              useGlobalPkgs = true;
              useUserPackages = true;
              users.cyryl = {
                imports = [./nixos/home-manager ./nixos/home-manager/linux.nix];
                _module.args.inputs = inputs;
                _module.args.system = system;
              };
            };
          }
        ];
        specialArgs = {inherit inputs system;};
      };
    mkRaspi = pkgs: hostname: let
      system = "aarch64-linux";
    in
      pkgs.lib.nixosSystem {
        inherit system;
        modules = [(./. + "/nixos/boxes/${hostname}") sops.nixosModules.sops];
        specialArgs = {inherit inputs system;};
      };
    mkKiosk = pkgs: system: hostname:
      pkgs.lib.nixosSystem {
        inherit system;
        modules = [
          (./. + "/nixos/boxes/${hostname}")
          (import ./nixos/common.nix)
          sops.nixosModules.sops

          home-manager.nixosModules.home-manager
          {
            home-manager = {
              useGlobalPkgs = true;
              useUserPackages = true;
              users.cyryl = {
                imports = [./nixos/home-manager ./nixos/home-manager/linux.nix];
                _module.args.inputs = inputs;
                _module.args.system = system;
              };
            };
          }
        ];
        specialArgs = {
          inherit inputs system;
          nixpkgs-nixos-stable-and-unfree = import nixpkgs-stable {
            inherit system;
            config = {allowUnfree = true;};
          };
          nixpkgs-nixos-unstable-and-unfree = import nixpkgs-nixos-unstable {
            inherit system;
            config = {allowUnfree = true;};
          };
        };
      };
    mkWorkstation = pkgs: system: hostname:
      pkgs.lib.nixosSystem {
        inherit system;
        modules = [
          lix-module.nixosModules.default
          (import ./nixos/options.nix)
          (./. + "/nixos/boxes/${hostname}")
          (import ./nixos/email-accounts.nix)
          (import ./nixos/common.nix)
          sops.nixosModules.sops
          disko.nixosModules.disko
          nix-ld.nixosModules.nix-ld
          {programs.nix-ld.dev.enable = true;}
          {nixpkgs.config.allowUnfree = true;}
          home-manager.nixosModules.home-manager
          {
            home-manager = {
              useGlobalPkgs = true;
              useUserPackages = true;
              users.cyryl = {
                imports = [./nixos/home-manager ./nixos/home-manager/linux.nix];
                _module.args.inputs = inputs;
                _module.args.system = system;
              };
            };
          }
        ];
        specialArgs = {
          inherit inputs system;
          resilio3 = import resilio3 {
            inherit system;
            config = {allowUnfree = true;};
          };
          nixpkgs-nixos-stable-and-unfree = import nixpkgs-stable {
            inherit system;
            config = {allowUnfree = true;};
          };
          nixpkgs-nixos-unstable =
            import nixpkgs-nixos-unstable {inherit system;};
          nixpkgs-nixos-unstable-and-unfree = import nixpkgs-nixos-unstable {
            inherit system;
            config = {allowUnfree = true;};
          };
        };
      };
    mkShell = packageSet: system: let
      pkgs = packageSet.legacyPackages.${system};
    in
      pkgs.mkShell {
        packages = with pkgs; [
          inputs.alejandra.defaultPackage.${system}
          cacert
          git
          git-lfs
          nixpkgs-fmt
          openssh
          openssl
          pkg-config
          statix
        ];
      };
  in {
    devShells = {
      "x86_64-darwin".default = mkShell nixpkgs-stable "x86_64-darwin";
      "aarch64-darwin".default = mkShell nixpkgs-stable "aarch64-darwin";
      "x86_64-linux".default = mkShell nixpkgs-stable "x86_64-linux";
      "aarch64-linux".default = mkShell nixpkgs-stable "aarch64-linux";
    };

    darwinConfigurations = {
      "cushy" = darwin.lib.darwinSystem rec {
        system = "aarch64-darwin";
        modules = [
          lix-module.nixosModules.default
          (import ./nixos/options.nix)
          (./. + "/nixos/boxes/cushy")
          {users.users."Cyryl.Plotnicki".home = "/Users/Cyryl.Plotnicki";}
          home-manager.darwinModules.home-manager
          {
            home-manager = {
              useGlobalPkgs = true;
              useUserPackages = true;
              users."Cyryl.Plotnicki" = {
                home.username = "Cyryl.Plotnicki";
                home.homeDirectory = "/Users/Cyryl.Plotnicki";
                programs.zsh.loginExtra = ''
                  eval "$(/opt/homebrew/bin/brew shellenv)"
                '';
                imports = [./nixos/home-manager];
                _module.args.inputs = inputs;
                _module.args.system = system;
              };
            };
          }
        ];
      };
      "airy" = darwin-master.lib.darwinSystem rec {
        system = "aarch64-darwin";
        modules = [
          (import ./nixos/options.nix)
          (./. + "/nixos/boxes/airy")
          {users.users.cyryl.home = "/Users/cyryl";}
          home-manager-master.darwinModules.home-manager
          {
            home-manager = {
              useGlobalPkgs = true;
              useUserPackages = true;
              users.cyryl = {
                home.homeDirectory = "/Users/cyryl";
                programs.zsh.loginExtra = ''
                  eval "$(/opt/homebrew/bin/brew shellenv)"
                '';
                imports = [./nixos/home-manager];
                _module.args.inputs = inputs;
                _module.args.system = system;
              };
            };
          }
        ];
      };
    };

    nixosConfigurations = {
      foryog = mkWorkstation nixpkgs-nixos-unstable "x86_64-linux" "foryog";
      thinky = mkWorkstation nixpkgs-stable "x86_64-linux" "thinky";
      bolty = mkPrivateServer nixpkgs-stable "x86_64-linux" "bolty";
      cupsnet = mkServer nixpkgs-stable "aarch64-linux" "cupsnet";
      mb1 = mkServer nixpkgs-stable "x86_64-linux" "mb1";
      airnix = mkServer nixpkgs-stable "aarch64-linux" "airnix";
      homescreen = mkRaspi nixpkgs-stable "homescreen";

      bootstrap = nixpkgs-stable.lib.nixosSystem rec {
        system = "x86_64-linux";
        modules = [(./. + "/nixos/boxes/bootstrap") sops.nixosModules.sops];
        specialArgs = {
          inherit inputs system;
          nixpkgs-nixos-unstable-and-unfree = import nixpkgs-nixos-unstable {
            inherit system;
            config = {allowUnfree = true;};
          };
        };
      };
      # nix build .#nixosConfigurations.raspiimage.config.system.build.sdImage
      # sudo dd if=result/sd-image/nixos-sd-image-21.11.20211201.a640d83-aarch64-linux.img of=/dev/sda bs=4M conv=fsync status=progress
      # make sure to update eeprom https://nixos.wiki/wiki/NixOS_on_ARM/Raspberry_Pi_4#Board-specific_installation_notes
      raspiimage = nixpkgs-stable.lib.nixosSystem {
        system = "aarch64-linux";
        modules = [
          (import
            "${inputs.nixpkgs-stable}/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix")
          {
            environment.systemPackages = with nixpkgs-nixos-unstable.legacyPackages."aarch64-linux"; [
              neovim
              htop
              btop
              atop
            ];

            networking.networkmanager.enable = false;
            hardware.enableRedistributableFirmware = true;
            networking.wireless.enable = true;

            services.openssh = {
              enable = true;
              permitRootLogin =
                nixpkgs-stable.lib.mkForce "prohibit-password";
              passwordAuthentication = false;
            };

            services.xserver = {
              enable = true;
              displayManager.lightdm.enable = true;
              desktopManager.gnome.enable = true;
              libinput.enable = true;
            };

            users.extraUsers.root.openssh.authorizedKeys.keys = [
              "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEo4R+6J3h6Ix3xWpOMdU7Es1/YxFchHw0c+kcCOJxFb cyryl@foureighty"
            ];
            sdImage.compressImage = false;
            console.earlySetup = true;
          }
        ];
        specialArgs = {inherit inputs;};
      };
      novenaimage = nixpkgs-stable.lib.nixosSystem {
        system = "armv7l-linux";
        modules = [
          (import
            "${inputs.nixpkgs-stable}/nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform-installer.nix")
          {
            environment.systemPackages = with nixpkgs-nixos-unstable.legacyPackages."armv7l-linux"; [
              neovim
              htop
              btop
              atop
            ];

            boot.kernelPackages = nixpkgs-stable.lib.mkForce nixpkgs-nixos-unstable.legacyPackages."armv7l-linux".linuxPackages_latest;
            boot.supportedFilesystems = nixpkgs-stable.lib.mkForce ["ext2" "ext4"];

            networking.networkmanager.enable = false;
            hardware.enableRedistributableFirmware = true;
            networking.wireless.enable = true;

            services.openssh = {
              enable = true;
              permitRootLogin =
                nixpkgs-stable.lib.mkForce "prohibit-password";
              passwordAuthentication = false;
            };

            services.xserver = {
              enable = true;
              displayManager.lightdm.enable = true;
              desktopManager.gnome.enable = true;
              libinput.enable = true;
            };

            users.extraUsers.root.openssh.authorizedKeys.keys = [
              "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEo4R+6J3h6Ix3xWpOMdU7Es1/YxFchHw0c+kcCOJxFb cyryl@foureighty"
            ];
            sdImage.compressImage = false;
            console.earlySetup = true;
          }
        ];
        specialArgs = {inherit inputs;};
      };
    };
  };
  inputs = {
    nixpkgs-master = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "master";
    };
    nixpkgs-nixos-unstable = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "nixos-unstable";
    };
    nixpkgs-stable = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "nixos-24.11";
    };
    nixpkgs-rust-analyzer = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "master";
    };
    endless-sky = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "2100c4926200b1ebbee032ad22113597195932f2";
    };
    resilio3 = {
      type = "github";
      owner = "cyplo";
      repo = "nixpkgs";
      ref = "4ca49d35b584e73b77cb4e496298729c1c3d2a7f";
    };
    nixos-hardware = {
      type = "github";
      owner = "NixOS";
      repo = "nixos-hardware";
      ref = "master";
    };
    darwin = {
      url = "github:lnl7/nix-darwin/master";
      inputs.nixpkgs.follows = "nixpkgs-stable";
    };
    darwin-master = {
      url = "github:lnl7/nix-darwin/master";
      inputs.nixpkgs.follows = "nixpkgs-master";
    };
    home-manager = {
      type = "github";
      owner = "nix-community";
      repo = "home-manager";
      ref = "release-24.11";
      inputs.nixpkgs.follows = "nixpkgs-stable";
    };
    home-manager-master = {
      type = "github";
      owner = "nix-community";
      repo = "home-manager";
      ref = "master";
      inputs.nixpkgs.follows = "nixpkgs-master";
    };
    flake-utils = {
      type = "github";
      owner = "numtide";
      repo = "flake-utils";
      ref = "main";
    };
    lix-module = {
      url = "https://git.lix.systems/lix-project/nixos-module/archive/2.91.1-2.tar.gz";
      inputs.nixpkgs.follows = "nixpkgs-stable";
      inputs.flake-utils.follows = "flake-utils";
    };
    nur = {
      type = "github";
      owner = "nix-community";
      repo = "NUR";
      ref = "master";
    };
    nil = {
      type = "github";
      owner = "oxalica";
      repo = "nil";
      ref = "main";
      inputs.nixpkgs.follows = "nixpkgs-nixos-unstable";
      inputs.flake-utils.follows = "flake-utils";
    };
    nix-ld = {
      type = "github";
      owner = "Mic92";
      repo = "nix-ld";
      ref = "main";
      inputs.nixpkgs.follows = "nixpkgs-stable";
    };
    helix = {
      type = "github";
      owner = "helix-editor";
      repo = "helix";
      ref = "master";
      inputs.nixpkgs.follows = "nixpkgs-stable";
      inputs.flake-utils.follows = "flake-utils";
    };
    sops = {
      type = "github";
      owner = "Mic92";
      repo = "sops-nix";
      ref = "master";
      inputs.nixpkgs.follows = "nixpkgs-stable";
    };
    alejandra = {
      type = "github";
      owner = "kamadorueda";
      repo = "alejandra";
      ref = "main";
      inputs.nixpkgs.follows = "nixpkgs-nixos-unstable";
    };
    disko = {
      url = "github:nix-community/disko";
      inputs.nixpkgs.follows = "nixpkgs-stable";
    };
    flake-compat = {
      url = "github:edolstra/flake-compat";
      flake = false;
    };
  };
}