{ pkgs, lib, config, inputs, ... }:
let
  inherit (config.boot) initrd;
  wgIface = "wg-intra";
  wg = config.networking.wireguard.interfaces.${wgIface};
  wg-intra-peers = import (inputs.julm-nix + "/nixos/profiles/wireguard/wg-intra/peers.nix");
  relay = wg-intra-peers.mermet;
in
{
  imports = [
    (inputs.julm-nix + "/nixos/profiles/wireguard/wg-intra.nix")
  ];
  networking.wireguard.${wgIface}.peers = {
    mermet.enable = true;
    oignon.enable = true;
    patate.enable = true;
    carotte.enable = true;
    aubergine.enable = true;
  };
  systemd.services."wireguard-${wgIface}" = {
    unitConfig.Upholds = [ "upnpc-${toString wg.listenPort}.service" ];
  };
  networking.nftables.ruleset = ''
    table inet filter {
      chain input-intra {
        tcp dport ssh counter accept comment "SSH"
        udp dport 60000-61000 counter accept comment "Mosh"
      }
      chain output-intra {
        tcp dport { ssh, 2222 } counter accept comment "SSH"
        udp dport 60001-60010 counter accept comment "Mosh"
        tcp dport { http, https } counter accept comment "HTTP"
        tcp dport git counter accept comment "Git"
      }
    }
    table inet nat {
      chain postrouting {
        iifname ${wgIface} oifname netIface masquerade
      }
    }
  '';
  # Apparently required to get NAT reflection.
  services.upnpc.enable = true;
  services.upnpc.redirections = [
    {
      description = "WireGuard";
      externalPort = wg.listenPort;
      protocol = "UDP";
      duration = 30 * 60;
      service.requiredBy = [ "wireguard-${wgIface}.service" ];
      service.before = [ "wireguard-${wgIface}.service" ];
    }
  ];
  boot.kernel.sysctl."net.ipv4.ip_forward" = 1;

  # Open a wireguard tunnel to a relay
  # in case the host is hosted behind a NAT and has no SSH port forwarding.
  # This enables to send the disk password to the initrd, like that:
  # ssh -J mermet.sourcephile.fr root@losurdo.wg -p 2222
  # TODO: use a dedicated interface wg-initrd
  boot.initrd.secrets."/root/initrd/${wgIface}.key" = "/run/credentials/wireguard-${wgIface}.service/privateKey";
  boot.initrd.kernelModules = [ "wireguard" ];
  boot.initrd.extraUtilsCommands = ''
    #copy_bin_and_libs ${pkgs.wireguard-tools}/bin/wg
    cp -fpdv ${pkgs.wireguard-tools}/bin/.wg-wrapped $out/bin/wg
  '';
  boot.initrd.network.postCommands = ''
    ip link add dev ${wgIface} type wireguard
    ${lib.concatMapStringsSep "\n" (ip: ''
      ip address add ${ip} dev ${wgIface}
    '') wg.ips}
    wg set ${wgIface} private-key /root/initrd/${wgIface}.key \
       listen-port ${toString wg.listenPort}
    ip link set up dev ${wgIface} mtu 1280
    wg set ${wgIface} peer ${relay.peer.publicKey} \
       endpoint ${relay.ipv4}:${toString relay.listenPort} \
       allowed-ips ${relay.ipv4}/32 \
       persistent-keepalive 5
    ip route replace ${relay.ipv4}/32 dev ${wgIface} table main
  '';
  boot.initrd.postMountCommands = lib.mkIf initrd.network.flushBeforeStage2 ''
    ip link del dev ${wgIface}
  '';
}