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

let wireguard_port = 1194;

in {
  # Enable systemd-networkd
  networking = {
    hostName = "zion";
    hostId = "4e74ea68";
    useDHCP = false;
    useNetworkd = true;
    dhcpcd.enable = false;
  };
  systemd.services."systemd-networkd-wait-online".enable = false;

  # Assign a static IP
  systemd.network.networks."24-home" = {
    name = "eth0";
    matchConfig.Name = "eth0";
    address = [ "192.168.13.2/24" ];
    gateway = [ "192.168.13.1" ];
    dns = [ "192.168.13.2" ];
    networkConfig.DNSSEC = "no";
  };

  # Enable zeroconf
  services.avahi = {
    enable = true;
    nssmdns = true;
    publish = {
      enable = true;
      userServices = true;
      domain = true;
      workstation = true;
    };
    reflector = true;
  };

  # Dynamic DNS configuration
  services.ddclient = {
    enable = true;
    quiet = true;
    protocol = "duckdns";
    domains = [ "coolneng.duckdns.org" ];
    passwordFile = config.age.secrets.ddclient.path;
  };

  # Firewall configuration
  networking.firewall = {
    allowedTCPPorts = [
      80 # HTTP
      443 # HTTPS
      53 # DNS
      8448 # Matrix
    ];
    allowedUDPPorts = [
      wireguard_port # Wireguard
      53 # DNS
    ];
    extraCommands = ''
      iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
    '';
  };

  # Wireguard setup
  systemd.network.netdevs."wg0" = {
    netdevConfig = {
      Kind = "wireguard";
      Name = "wg0";
    };
    wireguardConfig = {
      ListenPort = wireguard_port;
      PrivateKeyFile = config.age.secrets.wireguard.path;
    };
    wireguardPeers = [
      # panacea
      {
        wireguardPeerConfig = {
          PublicKey = "XMkTztU2Y8hw6Fu/2o4Gszij+EmNacvFMXuZyHS1n38=";
          AllowedIPs = [ "10.8.0.2/32" ];
        };
      }
      # caravanserai
      {
        wireguardPeerConfig = {
          PublicKey = "eeKfAgMisM3K4ZOErev05RJ9LS2NLqL4x9jyi4XhM1Q=";
          AllowedIPs = [ "10.8.0.3/32" ];
        };
      }
    ];
  };

  systemd.network.networks."wg0" = {
    matchConfig.Name = "wg0";
    networkConfig = {
      Address = "10.8.0.1/24";
      IPForward = true;
      IPMasquerade = "ipv4";
    };
  };

  # DNS server with ad-block
  services.dnsmasq = {
    enable = true;
    servers = [ "51.158.108.203" "137.220.55.93" ];
    extraConfig = ''
      domain-needed
      bogus-priv
      no-resolv

      listen-address=127.0.0.1,192.168.13.2,10.8.0.1
      bind-interfaces

      cache-size=10000
      local-ttl=300

      conf-file=/var/lib/dnsmasq/dnsmasq.blacklist.txt

      address=/coolneng.duckdns.org/192.168.13.2
    '';
  };

}