{ inputs, self, ... }:

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

  makeInstaller = import ./makeInstaller.nix;

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

  flake.isoInstallers.provisioning =
    let
      inherit (builtins) mapAttrs;
    in
    mapAttrs (
      vmname:
      makeInstaller {
        inherit (inputs) 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.feditest =
    { 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.${toString vmid}";
        ssh.hostPublicKey = readFile ./hostKeys/fedi${toString 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
              '';
            };
          }
        );

        fedi120 = makeProcolixVmResource 120 {
          fediversity = {
            enable = true;
            domain = "fedi120.abundos.eu";
            pixelfed.enable = true;
          };
        };
      };
    };
}