{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
    flake-parts.url = "github:hercules-ci/flake-parts";
    git-hooks.url = "github:cachix/git-hooks.nix";

    # snf.url = "path:/home/niols/git/fediversity/simple-nixos-fediverse"; #dev
    snf.url = "git+https://git.fediversity.eu/fediversity/simple-nixos-fediverse.git";
    disko.url = "github:nix-community/disko";

    nixops4.url = "github:nixops4/nixops4";
    nixops4-nixos.url = "github:nixops4/nixops4/eval";
  };

  outputs =
    inputs@{
      self,
      flake-parts,
      nixpkgs,
      snf,
      ...
    }:
    flake-parts.lib.mkFlake { inherit inputs; } {

      imports = [
        inputs.nixops4-nixos.modules.flake.default
        inputs.git-hooks.flakeModule
      ];

      systems = [
        "x86_64-linux"
        "aarch64-linux"
        "aarch64-darwin"
        "x86_64-darwin"
      ];

      perSystem =
        {
          config,
          inputs',
          pkgs,
          ...
        }:
        {
          formatter = pkgs.nixfmt-rfc-style;

          pre-commit.settings.hooks = {
            nixfmt-rfc-style.enable = true;
            deadnix.enable = true;
          };

          devShells.default = pkgs.mkShell {
            packages = [ inputs'.nixops4.packages.default ];
            shellHook = config.pre-commit.installationScript;
          };
        };

      flake.vmIdTo03d =
        id:
        let
          sid = toString id;
        in
        if id >= 0 && id <= 9 then
          "00${sid}"
        else if id >= 10 && id <= 99 then
          "0${sid}"
        else
          sid;

      flake.allVmIds = # 100 -- 255
        let
          allVmIdsFrom = x: if x > 255 then [ ] else [ x ] ++ allVmIdsFrom (x + 1);
        in
        allVmIdsFrom 100;

      flake.nixosConfigurations.provisioning =
        let
          inherit (builtins) map listToAttrs;
          makeProvisioningConfiguration =
            vmid:
            nixpkgs.lib.nixosSystem {
              modules = [
                { procolix.vmid = vmid; }
                ./procolixVm.nix
                inputs.disko.nixosModules.default
              ];
            };
        in
        listToAttrs (
          map (vmid: {
            name = "fedi${self.vmIdTo03d vmid}";
            value = makeProvisioningConfiguration vmid;
          }) self.allVmIds
        );

      flake.isoInstallers.provisioning =
        let
          inherit (builtins) mapAttrs;
        in
        mapAttrs (
          vmname:
          snf.mkInstaller {
            inherit nixpkgs;
            hostKeys = {
              rsa = {
                private = ./hostKeys/${vmname}/ssh_host_rsa_key;
                public = ./hostKeys/${vmname}/ssh_host_rsa_key.pub;
              };
              ed25519 = {
                private = ./hostKeys/${vmname}/ssh_host_ed25519_key;
                public = ./hostKeys/${vmname}/ssh_host_ed25519_key.pub;
              };
            };
          }
        ) self.nixosConfigurations.provisioning;

      nixops4Deployments.default =
        { providers, ... }:

        let
          inherit (builtins) readFile;

          makeProcolixVmResource = vmid: vmconfig: {
            type = providers.local.exec;
            imports = [ inputs.nixops4-nixos.modules.nixops4Resource.nixos ];
            ssh.opts = "";
            ssh.host = "95.215.187.${self.vmIdTo03d vmid}";
            ssh.hostPublicKey = readFile ./hostKeys/fedi${self.vmIdTo03d vmid}/ssh_host_ed25519_key.pub;

            nixpkgs = inputs.nixpkgs;
            nixos.module = {
              imports = [
                vmconfig
                { procolix.vmid = vmid; }
                ./procolixVm.nix
                inputs.snf.nixosModules.fediversity
                inputs.disko.nixosModules.default
              ];
            };
          };

        in
        {
          providers.local = inputs.nixops4-nixos.modules.nixops4Provider.local;

          resources = {
            fedi100 = makeProcolixVmResource 100 { };

            fedi101 = makeProcolixVmResource 101 {
              fediversity = {
                enable = true;
                domain = "fedi101.abundos.eu";
                pixelfed.enable = true;
              };
            };

            fedi102 = makeProcolixVmResource 102 {
              fediversity = {
                enable = true;
                domain = "fedi102.abundos.eu";
                mastodon.enable = true;

                temp.cores = 1; # FIXME: should come from NixOps4 eventually
              };
            };

            fedi103 = makeProcolixVmResource 103 (
              { pkgs, ... }:
              {
                fediversity = {
                  enable = true;
                  domain = "fedi103.abundos.eu";
                  peertube.enable = true;

                  temp.peertubeSecretsFile = pkgs.writeText "secret" ''
                    574e093907d1157ac0f8e760a6deb1035402003af5763135bae9cbd6abe32b24
                  '';
                };
              }
            );
          };
        };
    };
}