{
  lib,
  pkgs,
  ...
}: let
  inherit (pkgs) writeShellScriptBin;
  inherit (lib.lists) forEach;
  inherit (lib.strings) concatStringsSep optionalString;
  inherit (builtins) attrNames;

  wireguardData = import ../data/wireguard/chaosInternalWireGuard.nix;
  wireguardHosts = wireguardData.hosts;

  kvPathForHost = host: "/private-public-keys/wireguard/chaos-internal/${host}";
in rec {
  initAllScript = writeShellScriptBin "wg-keys-init-all" (let
    vault = "${pkgs.vault}/bin/vault";
  in ''

    PUBKEYS_FILE=$1
    if [ -z "$PUBKEYS_FILE" ]; then
      echo "please provide path to file with pubkeys"
      exit 1
    fi

    ${concatStringsSep "\n" (forEach (attrNames wireguardHosts) (hostName: ''
      echo "{}" | ${vault} kv put "${kvPathForHost hostName}" - 2>/dev/null
    ''))}

    ${concatStringsSep "\n" (forEach (attrNames wireguardHosts) (hostName: ''
      echo "Deploying keys for ${hostName}"

      "${genInitScript hostName}/bin/wg-keys-init-${hostName}" "$PUBKEYS_FILE"
    ''))}
  '');

  genInitScript = systemHostName: (writeShellScriptBin "wg-keys-init-${systemHostName}" (let
    vault = "${pkgs.vault}/bin/vault";
    jq = "${pkgs.jq}/bin/jq";
    wg = "${pkgs.wireguard-tools}/bin/wg";
    sponge = "${pkgs.moreutils}/bin/sponge";
  in ''

    PUBKEYS_FILE=$1
    if [ -z "$PUBKEYS_FILE" ]; then
      echo "please provide path to file with pubkeys"
      exit 1
    fi

    PRIVATE=$(${wg} genkey)
    PUBLIC=$(echo "$PRIVATE" | ${wg} pubkey)

    TMP_DIR=$(mktemp -d)
    pushd "$TMP_DIR"
    echo "{}" > currentHost.json
    ${jq} ".public = \"$PUBLIC\"" currentHost.json | ${sponge} currentHost.json
    ${jq} ".private = \"$PRIVATE\"" currentHost.json | ${sponge} currentHost.json
    cat currentHost.json | ${vault} kv put "${kvPathForHost systemHostName}" - 2>/dev/null
    cat currentHost.json | jq
    popd

    rm -rf "$TMP_DIR"

    ${jq} ".\"${systemHostName}\" = \"$PUBLIC\"" "$PUBKEYS_FILE" | ${sponge} "$PUBKEYS_FILE"
  ''));

  genConfScript = systemHostName: (writeShellScriptBin "wg-gen-conf-${systemHostName}" (let
    vault = "${pkgs.vault}/bin/vault";
    jq = "${pkgs.jq}/bin/jq";

    currentHostConfig = wireguardHosts.${systemHostName};
  in ''
    set -euo pipefail
    getPrivateKey() {
      ${vault} kv get -format=json "/private-public-keys/wireguard/chaos-internal/$1" | ${jq} -r ".data.data.private" | tr -d '\n'
    }

    cat << EOF
    [interface]
    Address = ${currentHostConfig.ip}/24
    ${optionalString (currentHostConfig ? "listenAddress") "ListenAddress = ${toString currentHostConfig.listenAddress}"}
    PrivateKey = $(getPrivateKey ${systemHostName})


    ${concatStringsSep "\n" (forEach (attrNames wireguardHosts) (hostName: (let
      hostConfig = wireguardHosts.${hostName};
    in ''
      [Peer]
      PublicKey = ${hostConfig.public}
      ${optionalString (hostConfig ? "endpoint") "Endpoint = ${hostConfig.endpoint}"}
      AllowedIPs = ${
        if hostConfig ? "allowedIPs"
        then concatStringsSep "," hostConfig.allowedIPs
        else "${hostConfig.ip}/32"
      }
    '')))}
    EOF
  ''));
}