{
  config,
  lib,
  ...
}: let
  cfg = config.soispha.networking;
in {
  options.soispha.networking = {
    enable = lib.mkEnableOption "networking";

    mode = lib.mkOption {
      type = lib.types.enum ["NetworkManager" "systemd-networkd"];
      example = "systemd-networkd";
      description = "The daemon used to setup networking.";
    };

    userName = lib.mkOption {
      type = lib.types.str;
      default = "soispha";
      description = ''
        The name of the user to allow access to the configured network
      '';
    };

    hostName = lib.mkOption {
      type = lib.types.str;
      example = "apzu";
      description = "The name of the host";
    };
  };

  config =
    lib.mkIf cfg.enable
    (lib.modules.mkMerge [
      {
        networking.hostName = cfg.hostName;
      }
      (lib.mkIf (cfg.mode == "systemd-networkd") {
        systemd.network = {
          networks = {
            "tap0" = {
              name = "tap0";
              bridge = [
                "virbr0"
              ];
            };
            "enp4s0" = {
              name = "enp4s0";
              networkConfig = {
                DHCP = "yes";
                DNSOverTLS = "yes";
                DNSSEC = "yes";
              };
              bridge = [
                "virbr0"
              ];
            };
          };

          netdevs = {
            "tap0" = {
              netdevConfig = {
                Name = "tap0";
                Kind = "tap";
              };
              tapConfig = {
                User = config.users.users."${cfg.userName}".uid;
                Group = "libvirtd";
              };
            };
            "virbr0" = {
              netdevConfig = {
                Name = "br0";
                Kind = "bridge";
              };
            };
          };
        };
      })

      (lib.mkIf (cfg.mode == "NetworkManager") {
        networking.networkmanager = {
          enable = true;
          dns = "default";
          wifi = {
            powersave = true;
          };
        };

        soispha.impermanence.directories = [
          "/etc/NetworkManager"
        ];

        users.users."${cfg.userName}".extraGroups = [
          "networkmanager" # allows to configure NetworkManager as this user
        ];
      })
    ]);
}