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

with lib;

let
  trim = str: if hasSuffix "\n" str then trim (removeSuffix "\n" str) else str;
  prefix4 = "10.84.47";
  prefix6 = "2a03:4000:52:ada:5";
in {
  config = {
    boot.kernel.sysctl = {
      "net.netfilter.nf_log_all_netns" = true;
    };

    networking.namespaces = {
      enable = true;
      containers."vpn".config = {
        boot.kernel.sysctl = {
          "net.core.rmem_max" = 4194304;
          "net.core.wmem_max" = 4194304;
        };

        environment = {
          noXlibs = true;
          systemPackages = with pkgs; [ wireguard-tools ];
        };

        networking = {
          useDHCP = false;
          useNetworkd = true;
          useHostResolvConf = false;
          firewall.enable = false;
          nftables = {
            enable = true;
            rulesetFile = ./ruleset.nft;
          };
        };

        services.resolved.fallbackDns = [
          "9.9.9.10#dns10.quad9.net"
          "149.112.112.10#dns10.quad9.net"
          "2620:fe::10#dns10.quad9.net"
          "2620:fe::fe:10#dns10.quad9.net"
        ];

        systemd.services."systemd-networkd" = {
          serviceConfig = {
            LoadCredential = [
              "surtr.priv"
            ];
          };
        };

        systemd.network = {
          netdevs = {
            vpn = {
              netdevConfig = {
                Name = "vpn";
                Kind = "wireguard";
              };
              wireguardConfig = {
                PrivateKeyFile = "/run/credentials/systemd-networkd.service/surtr.priv";
                ListenPort = 51820;
              };
              wireguardPeers = imap1 (i: { name, ip ? i }: {
                wireguardPeerConfig = {
                  AllowedIPs = ["${prefix6}:${toString ip}::/96" "${prefix4}.${toString ip}/32"];
                  PublicKey = trim (readFile (./. + "/${name}.pub"));
                };
              }) [ { name = "geri"; } { name = "sif"; } ];
            };
          };

          networks = {
            upstream = {
              name = "upstream";
              matchConfig = {
                Name = "upstream";
              };
              linkConfig = {
                RequiredForOnline = true;
              };
              networkConfig = {
                Address = [ "185.243.10.86/32" "2a03:4000:20:259::/64" ];
                LLMNR = false;
                MulticastDNS = false;
              };
              routes = [
                { routeConfig = {
                    Destination = "202.61.240.1";
                  };
                }
                { routeConfig = {
                    Destination = "0.0.0.0/0";
                    Gateway = "202.61.240.1";
                  };
                }
                { routeConfig = {
                    Destination = "::/0";
                    Gateway = "fe80::1";
                  };
                }
              ];
              extraConfig = ''
                [Neighbor]
                Address=202.61.240.1
                LinkLayerAddress=00:00:5e:00:01:01
              '';
            };
            vpn = {
              name = "vpn";
              matchConfig = {
                Name = "vpn";
              };
              address = ["${prefix6}::/96" "${prefix4}.0/32"];
              routes = [
                { routeConfig = {
                    Destination = "${prefix6}::/80";
                  };
                }
                { routeConfig = {
                    Destination = "${prefix4}.0/24";
                  };
                }
              ];
              linkConfig = {
                RequiredForOnline = false;
              };
              networkConfig = {
                LLMNR = false;
                MulticastDNS = false;
              };
            };
          };
        };
      };
    };

    systemd.services = {
      "vpn-upstream" = {
        bindsTo = ["netns@vpn.service"];
        after = ["netns@vpn.service"];
        serviceConfig = {
          Type = "oneshot";
          RemainAfterExit = true;
          ExecStop = "${pkgs.iproute2}/bin/ip netns exec vpn ip link delete upstream";
        };
        path = with pkgs; [ iproute2 procps ];
        script = ''
          ip netns exec vpn sysctl \
            net.ipv6.conf.all.forwarding=1 \
            net.ipv6.conf.default.forwarding=1 \
            net.ipv4.conf.all.forwarding=1 \
            net.ipv4.conf.default.forwarding=1

          ip link add link ens3 name upstream type ipvlan mode l2
          ip link set upstream netns vpn
        '';
      };

      "netns-container@vpn" = {
        wantedBy = ["multi-user.target" "network-online.target"];
        after = ["vpn-upstream.service"];
        bindsTo = ["vpn-upstream.service"];

        serviceConfig = {
          LoadCredential = [
            "surtr.priv:${config.sops.secrets.vpn.path}"
          ];
        };
      };
    };

    sops.secrets.vpn = {
      format = "binary";
      sopsFile = ./surtr.priv;
    };
  };
}