{ flake, pkgs, customUtils, lib, config, path, ... }:
let
  mwnSubnetsPublic =
    [ "129.187.0.0/16" "141.40.0.0/16" "141.84.0.0/16"
      "192.68.211.0/24" "192.68.212.0/24" "192.68.213.0/24" "192.68.214.0/24" "192.68.215.0/24"
      "193.174.96.0/22"
      "194.95.59.0/24"
    ];
  mwnSubnetsPrivate =
    [ "10.153.0.0/16" "10.162.0.0/16" "10.156.0.0/16"
    ];
in {
  imports = with flake.nixosModules.systemProfiles; [
    ./hw.nix
    ./mail
    initrd-all-crypto-modules default-locale openssh rebuild-machines
    networkmanager
  ];

  config = {
    nixpkgs = {
      system = "x86_64-linux";
      config = {
        allowUnfree = true;
        pulseaudio = true;
      };
    };

    time.timeZone = null;

    boot = {
      initrd = {
        luks.devices = {
          nvm0 = { device = "/dev/disk/by-uuid/fe641e81-0812-4181-a5f6-382ebba509bb"; bypassWorkqueues = true; };
          nvm1 = { device = "/dev/disk/by-uuid/43df1ba8-1728-4193-8855-920a82d4494a"; bypassWorkqueues = true; };
        };
        availableKernelModules = [ "drbg" "nvme" "xhci_pci" "usb_storage" "sd_mod" "sr_mod" "rtsx_pci_sdmmc" ];
        kernelModules = [ "dm-raid" "dm-integrity" "dm-snapshot" "dm-thin-pool" "dm-mod" "dm-crypt" ];
      };

      supportedFilesystems = [ "nfs" "nfs4" ];

      blacklistedKernelModules = [ "nouveau" ];

      # Use the systemd-boot EFI boot loader.
      loader = {
        systemd-boot = {
          enable = true;
          configurationLimit = 15;
        };
        efi.canTouchEfiVariables = true;
        timeout = null;
      };

      plymouth.enable = true;

      kernelPackages = pkgs.linuxPackages_latest;
      kernelParams = [ "i915.fastboot=1" "intel_pstate=no_hwp" "acpi_backlight=vendor" "thinkpad-acpi.brightness_enable=1" "quiet" ];
      extraModulePackages = with config.boot.kernelPackages; [ v4l2loopback ];
      kernelModules = ["v4l2loopback"];
      kernelPatches = [
        { name = "edac-config";
          patch = null;
          extraConfig = ''
            EDAC y
            EDAC_IE31200 y
          '';
        }
      ];

      tmpOnTmpfs = true;

      kernel.sysctl = {
        "net.ipv4.ip_forward" = true;
        "net.ipv6.conf.all.forwarding" = true;
      };
    };

    services.timesyncd.enable = false;
    services.chrony = {
      enable = true;
      servers = [];
      extraConfig = ''
        pool time.cloudflare.com iburst nts
        pool nts.ntp.se iburst nts
        server nts.sth1.ntp.se iburst nts
        server nts.sth2.ntp.se iburst nts
        server ptbtime1.ptb.de iburst nts
        server ptbtime2.ptb.de iburst nts
        server ptbtime3.ptb.de iburst nts

        leapsectz right/UTC

        makestep 0.1 3

        cmdport 0
      '';
    };

    networking = {
      domain = "yggdrasil";
      search = [ "yggdrasil" ];
      hosts = {
        "127.0.0.1" = [ "sif.yggdrasil" "sif" ];
        "::1" = [ "sif.yggdrasil" "sif" ];
      };

      firewall.enable = false;
      nftables = {
        enable = true;
        rulesetFile = ./ruleset.nft;
      };

      # firewall = {
      #   enable = true;
      #   allowedTCPPorts = [ 22 # ssh
      #                       8000 # quickserve
      #                     ];
      # };

      # wlanInterfaces = {
      #   wlan0 = {
      #     device = "wlp82s0";
      #   };
      # };

      # bonds = {
      #   "lan" = {
      #     interfaces = [ "wlan0" "enp0s31f6" "dock0" ];
      #     driverOptions = {
      #       miimon = "1000";
      #       mode = "active-backup";
      #       primary_reselect = "always";
      #     };
      #   };
      # };

      useDHCP = false;
      useNetworkd = true;

      # interfaces."tinc.yggdrasil" = {
      #   virtual = true;
      #   virtualType = config.services.tinc.networks.yggdrasil.interfaceType;
      #   macAddress = "5c:93:21:c3:61:39";
      # };
    };

    environment.etc."NetworkManager/dnsmasq.d/libvirt_dnsmasq.conf" = {
      text = ''
        except-interface=virbr0
        server=/libvirt/192.168.122.1@virbr0
      '';
    };
    environment.etc."NetworkManager/dnsmasq.d/wgrz.conf" = {
      text = ''
        server=/mathinst.loc/10.153.88.9@wgrz
        server=/cipmath.loc/10.153.88.9@wgrz
      '';
    };
    environment.etc."NetworkManager/dnsmasq.d/yggdrasil.conf" = {
      text = ''
        server=/yggdrasil/2a03:4000:52:ada:1:1::@yggdrasil
        server=/141.10.in-addr.arpa/2a03:4000:52:ada:1:1::@yggdrasil
        server=/1.0.0.0.a.d.a.0.2.5.0.0.0.0.0.4.3.0.a.2.ip6.arpa/2a03:4000:52:ada:1:1::@yggdrasil
      '';
    };

    systemd.network = {
      netdevs = {
        wgrz = {
          netdevConfig = {
            Name = "wgrz";
            Kind = "wireguard";
          };
          wireguardConfig = {
            PrivateKeyFile = "/run/credentials/systemd-networkd.service/wgrz.priv";
            ListenPort = 51822;
            # FirewallMark = 1;
          };
          wireguardPeers = [
            { wireguardPeerConfig = {
                AllowedIPs = [ "10.200.116.1/32" ] ++ mwnSubnetsPrivate ++ mwnSubnetsPublic;
                PublicKey = "YlRFLc+rD2k2KXl7pIJbOKbcPgdJCl8ZTsv0xlK4VEI=";
                PersistentKeepalive = 25;
                Endpoint = "wg.math.lmu.de:51820";
              };
            }
          ];
        };
        virbr0 = {
          netdevConfig = {
            Name = "virbr0";
            Kind = "bridge";
            MACAddress = "52:54:00:18:85:5b";
          };
        };
      };
      networks = {
        wgrz = {
          name = "wgrz";
          matchConfig = {
            Name = "wgrz";
          };
          address = ["10.200.116.128/24"];
          routes = map (Destination: { routeConfig = {
            inherit Destination;
            Gateway = "10.200.116.1";
            GatewayOnLink = true;
            Table = "wgrz";
          };}) (mwnSubnetsPrivate ++ mwnSubnetsPublic);
          routingPolicyRules = [
            { routingPolicyRuleConfig = {
                Table = "main";
                # FirewallMark = 1;
                To = "129.187.111.225";
                Priority = 100;
              };
            }
            { routingPolicyRuleConfig = {
                Table = "main";
                To = "10.153.91.204";
                Priority = 100;
              };
            }
            { routingPolicyRuleConfig = {
                Table = "wgrz";
                From = "10.200.116.128";
                Priority = 200;
              };
            }
          ] ++ map (To: { routingPolicyRuleConfig = {
                            Table = "wgrz";
                            inherit To;
                            Priority = 200;
                          };}) (mwnSubnetsPrivate ++ mwnSubnetsPublic);
          linkConfig = {
            RequiredForOnline = false;
          };
          networkConfig = {
            LLMNR = false;
            MulticastDNS = false;
            DNS = ["10.153.88.9" "129.187.111.202" "10.156.33.53"];
          };
        };
        virbr0 = {
          name = "virbr0";
          matchConfig = {
            Name = "virbr0";
          };
          address = ["192.168.122.1/24" "fd45:febc:b028::/48"];
          networkConfig = {
            ConfigureWithoutCarrier = true;
            LLMNR = false;
            MulticastDNS = false;
          };
        };
      };
      config.routeTables.wgrz = 1025;
    };
    sops.secrets.wgrz = {
      format = "binary";
      sopsFile = ./wgrz/privkey;
    };
    networking.networkmanager.unmanaged = ["wgrz" "virbr0"];
    systemd.services."systemd-networkd".serviceConfig.LoadCredential = [
      "wgrz.priv:${config.sops.secrets.wgrz.path}"
    ];

    services.dnsmasq = {
      enable = true;
      resolveLocalQueries = false;
      settings = {
        enable-ra = true;
        local = "/libvirt/";
        domain-needed = true;
        expand-hosts = true;
        bogus-priv = true;
        no-hosts = true;
        listen-address = [ "192.168.122.1" "fd45:febc:b028::" ];
        interface = "virbr0";
        except-interface = "lo";
        bind-interfaces = true;
        domain = "libvirt,192.168.122.0/24";
        dhcp-range = [ "192.168.122.128,192.168.122.254,1h" "fd45:febc:b028::1,fd45:febc:b028:0:ffff:ffff:ffff:ffff,ra-names,1h" ];
        dhcp-host = [ "52:54:00:18:85:5b,sif,192.168.122.1" ];
        dhcp-authoritative = true;
        dhcp-rapid-commit = true;
        dhcp-option = "option6:dns-server,[fd45:febc:b028::]";
      };
    };
    systemd.services.dnsmasq = {
      bindsTo = ["sys-subsystem-net-devices-virbr0.device"];
      after = ["sys-subsystem-net-devices-virbr0.device"];
    };
    systemd.services.libvirtd = {
      wants = ["dnsmasq.service"];
      bindsTo = ["sys-subsystem-net-devices-virbr0.device"];
      after = ["dnsmasq.service" "sys-subsystem-net-devices-virbr0.device"];
    };

    services.openssh = {
      enable = true;
      settings = {
        PasswordAuthentication = true;
        KbdInteractiveAuthentication = true;
      };
    };

    powerManagement = {
      enable = true;

      cpuFreqGovernor = "schedutil";
    };

    environment.systemPackages = with pkgs; [
      nvtop brightnessctl config.boot.kernelPackages.v4l2loopback s-tui uhk-agent
    ];

    services = {
      uucp = {
        enable = true;
        nodeName = "sif";
        remoteNodes = {
          "ymir" = {
            publicKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG6KNtsCOl5fsZ4rV7udTulGMphJweLBoKapzerWNoLY root@ymir"];
            hostnames = ["ymir.yggdrasil.li" "ymir.niflheim.yggdrasil"];
          };
        };

        defaultCommands = lib.mkForce [];
      };

      avahi.enable = true;

      fwupd.enable = true;

      fprintd.enable = true;

      blueman.enable = true;

      colord.enable = true;

      vnstat.enable = true;

      upower.enable = true;

      thinkfan.enable = true;

      logind = {
        lidSwitch = "suspend";
        lidSwitchDocked = "lock";
        lidSwitchExternalPower = "lock";
      };

      atd = {
        enable = true;
        allowEveryone = true;
      };

      xserver = {
        enable = true;

        layout = "us";
        xkbVariant = "dvp";
        xkbOptions = "compose:caps";

        displayManager.lightdm = {
          enable = true;
          greeters.gtk = {
            clock-format = "%H:%M %a %b %_d";
            indicators = ["~host" "~spacer" "~clock" "~session" "~power"];
            theme = {
              package = pkgs.equilux-theme;
              name = "Equilux-compact";
            };
            iconTheme = {
              package = pkgs.paper-icon-theme;
              name = "Paper";
            };
            extraConfig = ''
              background = #000000
              user-background = false
              active-monitor = #cursor
              hide-user-image = true

              [monitor: DP-2]
                laptop = true
            '';
          };
        };

        wacom.enable = true;
        libinput.enable = true;

        dpi = 282;

        videoDrivers = [ "nvidia" ];

        screenSection = ''
          Option "metamodes" "nvidia-auto-select +0+0 { ForceCompositionPipeline = On }"
        '';

        deviceSection = ''
          Option "TearFree" "True"
        '';

        exportConfiguration = true;
      };
    };

    users = {
      users.gkleen.extraGroups = [ "media" "plugdev" "input" ];
      groups.media = {};
      groups.plugdev = {};
      groups.input = {};
    };

    security.rtkit.enable = true;
    services.pipewire = {
      enable = true;
      alsa.enable = true;
      alsa.support32Bit = true;
      pulse.enable = true;
      jack.enable = true;
      media-session.enable = false;
      wireplumber.enable = true;
      config.pipewire = {
        "context.properties" = {
          "log.level" = 2;
          "core.daemon" = true;
          "core.name" = "pipewire-0";
        };
        "context.modules" = [
          {
            name = "libpipewire-module-rtkit";
            args = {
              "nice.level" = -15;
              "rt.prio" = 88;
              "rt.time.soft" = 200000;
              "rt.time.hard" = 200000;
            };
            flags = [ "ifexists" "nofail" ];
          }
          { name = "libpipewire-module-protocol-native"; }
          { name = "libpipewire-module-profiler"; }
          { name = "libpipewire-module-metadata"; }
          { name = "libpipewire-module-spa-device-factory"; }
          { name = "libpipewire-module-spa-node-factory"; }
          { name = "libpipewire-module-client-node"; }
          { name = "libpipewire-module-client-device"; }
          {
            name = "libpipewire-module-portal";
            flags = [ "ifexists" "nofail" ];
          }
          {
            name = "libpipewire-module-access";
            args = {};
          }
          { name = "libpipewire-module-adapter"; }
          { name = "libpipewire-module-link-factory"; }
          { name = "libpipewire-module-session-manager"; }
        ];
      };
      config.pipewire-pulse = {
        "context.properties" = {
          "log.level" = 2;
        };
        "context.modules" = [
          {
            name = "libpipewire-module-rtkit";
            args = {
              "nice.level" = -15;
              "rt.prio" = 88;
              "rt.time.soft" = 200000;
              "rt.time.hard" = 200000;
            };
            flags = [ "ifexists" "nofail" ];
          }
          { name = "libpipewire-module-protocol-native"; }
          { name = "libpipewire-module-client-node"; }
          { name = "libpipewire-module-adapter"; }
          { name = "libpipewire-module-metadata"; }
          {
            name = "libpipewire-module-protocol-pulse";
            args = {
              "server.address" = [ "unix:native" ];
            };
          }
        ];
        "stream.properties" = {
          "resample.quality" = 1;
        };
      };
    };

    hardware = {
      bluetooth = {
        enable = true;
        package = pkgs.bluez;
        settings = {
          General = {
            Enable = "Source,Sink,Media,Socket";
          };
        };
      };

      trackpoint = {
        enable = true;
        emulateWheel = true;
        sensitivity = 255;
        speed = 255;
      };

      nvidia = {
        modesetting.enable = true;
        powerManagement.enable = true;
        prime = {
          nvidiaBusId = "PCI:1:0:0";
          intelBusId = "PCI:0:2:0";
          sync.enable = true;
        };
      };

      opengl = {
        enable = true;
        driSupport32Bit = true;
        setLdLibraryPath = true;
      };

      firmware = [ pkgs.firmwareLinuxNonfree ];

      keyboard.uhk.enable = true;
    };

    sound.enable = true;

    nix = {
      settings.auto-optimise-store = true;
      daemonCPUSchedPolicy = "idle";
      daemonIOSchedClass = "idle";

      buildServers.vidhar = let
        vidhar = flake.nixosConfigurations.vidhar;
      in {
        address = "vidhar.yggdrasil";
        systems = [vidhar.config.nixpkgs.system] ++ vidhar.config.nix.settings.extra-platforms;
        supportedFeatures = vidhar.config.nix.settings.system-features;
        maxJobs = 12;
        speedFactor = 4;
      };
    };

    environment.etc."X11/xorg.conf.d/50-wacom.conf".source = lib.mkForce ./wacom.conf;

    systemd.services."ac-plugged" = {
      description = "Inhibit handling of lid-switch and sleep";

      path = with pkgs; [ systemd coreutils ];

      script = ''
        exec systemd-inhibit --what=handle-lid-switch --why="AC is connected" --mode=block sleep infinity
      '';

      serviceConfig = {
        Type = "simple";
      };
    };

    services.udev.extraRules = with pkgs; lib.mkAfter ''
      SUBSYSTEM=="power_supply", ENV{POWER_SUPPLY_ONLINE}=="0", RUN+="${systemd}/bin/systemctl --no-block stop ac-plugged.service"
      SUBSYSTEM=="power_supply", ENV{POWER_SUPPLY_ONLINE}=="1", RUN+="${systemd}/bin/systemctl --no-block start ac-plugged.service"
    '';

    services.btrfs.autoScrub = {
      enable = true;
      fileSystems = [ "/" "/home" ];
      interval = "weekly";
    };

    systemd.services."nix-daemon".serviceConfig = {
      MemoryAccounting = true;
      MemoryHigh = "50%";
      MemoryMax = "75%";
    };

    services.journald.extraConfig = ''
      SystemMaxUse=100M
    '';

    services.dbus.packages = with pkgs;
      [ dbus dconf
      ];

    services.udisks2.enable = true;

    programs = {
      light.enable = true;
      wireshark.enable = true;
      dconf.enable = true;
    };

    virtualisation.libvirtd = {
      enable = true;
    };

    zramSwap.enable = true;

    services.pcscd.enable = true;

    sops.secrets.gkleen-rclone = {
      sopsFile = ./gkleen-rclone.yaml;
      key = "passphrase";
      owner = "gkleen";
      group = "users";
    };

    i18n.inputMethod.enabled = "ibus";

    environment.sessionVariables."GTK_USE_PORTAL" = "1";
    xdg.portal = {
      enable = true;
      # gtkUsePortal = true;
      extraPortals = let
        gtk-portal = pkgs.xdg-desktop-portal-gtk.overrideAttrs (oldAttrs: {
          postFixup = ''
            ${oldAttrs.postFixup or ""}

            ${pkgs.gnused}/bin/sed -ri \
              's|UseIn=gnome|UseIn=gnome;none+xmonad|' \
              $out/share/xdg-desktop-portal/portals/gtk.portal
          '';
        });
      in [ gtk-portal ];
    };

    system.stateVersion = "20.03";
  };
}