{
  pkgs,
  lib,
  config,
  ...
}:

let
  cfg = config.services.rosenpassKeySync;
  servicePrefix = "rp-key-sync-";
  timerPrefix = "rp-key-sync-timer-";
  rpKeySyncOpts =
    { name, ... }:
    {
      # Each instance of ths service is defined by the following information:
      options = {
        create = lib.mkEnableOption "RP Keysync for ${name}";

        enable = lib.mkOption {
          type = lib.types.bool;
          description = "Should the service be enabled";
          default = true;
        };

        wgInterface = lib.mkOption {
          type = lib.types.str;
          description = "Wireguard interface name";
        };

        rpHost = lib.mkOption {
          type = lib.types.str;
          description = "network address of the host that runs rosenpass";
        };

        peerPubkeyFile = lib.mkOption {
          type = lib.types.path;
          description = "Public key of wireguard peer";
        };

        remoteKeyPath = lib.mkOption {
          type = lib.types.path;
          description = "Location of the .osk file on the key exchange server";
        };

        endpoint = lib.mkOption {
          type = lib.types.str;
          description = "IP address of the peer to connect via.";
        };

        allowedIps = lib.mkOption {
          type = lib.types.str;
          description = "IP addresses on the WireGuard VPN the peer is allowed to use";
        };
      };
    };
in
{
  options.services.rosenpassKeySync = {
    instances = lib.mkOption {
      type = lib.types.attrsOf (lib.types.submodule rpKeySyncOpts);
      default = { };
      description = "RP key sync instances";
    };
  };

  config = {
    systemd.services = lib.mapAttrs' (instanceName: instanceCfg: {
      name = "${servicePrefix}${instanceName}";
      value = {
        description = "Rosenpass Key Downloader ${instanceName}";
        wantedBy = [ ] ++ lib.optional instanceCfg.enable "multi-user.target"; # If we set enable to this, then the service will be masked and cannot be enabled. Doing it this way allows us to enable it.
        requires = [ "network-online.target" ];
        # The script downloads the key generated by rosenpass from the key exchange node and sets it as the preshared key for the specified wireguard peer.
        script = ''
          set -euo pipefail
          PEER_PUB_KEY=$(cat ${instanceCfg.peerPubkeyFile})
          ${pkgs.openssh}/bin/ssh ${instanceCfg.rpHost} "cat ${instanceCfg.remoteKeyPath}" \
            | ${pkgs.wireguard-tools}/bin/wg \
              set ${instanceCfg.wgInterface} \
              peer $PEER_PUB_KEY \
              endpoint ${instanceCfg.endpoint} \
              allowed-ips ${instanceCfg.allowedIps} \
              preshared-key /dev/stdin
        '';
        serviceConfig = {
          Restart = "always";
          RestartSec = 10;
        };
      };
    }) (lib.filterAttrs (_: cfg: cfg.create) cfg.instances); # this creates one systemd service (as above) per configured instance.

    systemd.timers = lib.mapAttrs' (instanceName: instanceCfg: {
      name = "${timerPrefix}${instanceName}";
      value = {
        wantedBy = [ "timers.target" ];
        timerConfig = {
          requires = [ "network-online.target" ];
          OnUnitActiveSec = "1m";
          Unit = "${servicePrefix}${instanceName}.service";
        };
      };
    }) (lib.filterAttrs (_: cfg: cfg.create) cfg.instances); # this creates one systemd timer  (as above) per configured instance.
  };
}
