inputs:
{ config, lib, pkgs, ... }: {
  nix = {
    package = pkgs.nixStable;
    extraOptions = ''
      experimental-features = nix-command flakes
    '';
    settings = {
      substituters = lib.mkForce [
        "https://cache.nixos.org/"
        "https://nix-community.cachix.org"
      ];
      trusted-public-keys = [
        "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
      ];
    };
    # nix shell and nix build should use the same channel as the flake
    registry.nixpkgs.flake = inputs.nixpkgs;
  };
  nixpkgs.config.allowUnfree = true;

  networking = {
    networkmanager.enable = true;
  };

  i18n.defaultLocale = "en_GB.UTF-8";
  time.timeZone = "Europe/Berlin";

  #sound.enable = true;

  hardware = {
    # TODO: remove
    enableAllFirmware = true;
    #pulseaudio = {
      # TODO: pipewire
      #enable = true;
      # stop mumble from muting other processes
      #extraConfig = "unload-module module-role-cork";
    #};
    graphics = {
      enable = true;
      # driSupport = true;
      enable32Bit = true;
    };
  };

  services = {
    tailscale.enable = true;
    # yubikey smartcard mode
    pcscd.enable = true;
    dbus.packages = with pkgs; [ gcr ];
    # for u2f stick and yubikey
    udev.packages = with pkgs; [ libu2f-host yubikey-personalization ];
    davfs2.enable = true;

    /* local caching DNS resolver */
    /* unbound.enable = true; */
    resolved.enable = true;

    /* mount as user */
    udisks2.enable = true;
    gvfs = {
      enable = true;
      package = pkgs.gvfs;
    };

    # Enable CUPS to print documents.
    printing.enable = true;

    pipewire = {
      enable = true;
      alsa.enable = true;
      alsa.support32Bit = true;
      pulse.enable = true;
      wireplumber.enable = true;
    };
    # required for nextcloud
    gnome.gnome-keyring.enable = true;

    # faster entropy generation
    haveged.enable = true;

    mullvad-vpn.enable = true;

    fwupd = {
      enable = true;
    };

    displayManager = {
      #defaultSession = "none+i3";
      defaultSession = "sway";
    };

    xserver = {
      enable = true;

      xkb = {
        options = "caps:escape";
        layout = "eu";
      };

      displayManager = {
        gdm.enable = true;
      };

      windowManager.i3 = {
        enable = true;
      };
    };
  };

  systemd.tmpfiles.rules = [
    "L+ /lib64/ld-linux-x86-64.so.2 - - - - ${pkgs.glibc}/lib64/ld-linux-x86-64.so.2"
  ];

  # pipewire bluetooth config (https://nixos.wiki/wiki/PipeWire#Bluetooth_Configuration)
  environment.etc = {
    "wireplumber/bluetooth.lua.d/51-bluez-config.lua".text = ''
      bluez_monitor.properties = {
        ["bluez5.enable-sbc-xq"] = true,
        ["bluez5.enable-msbc"] = true,
        ["bluez5.enable-hw-volume"] = true,
        ["bluez5.headset-roles"] = "[ hsp_hs hsp_ag hfp_hf hfp_ag ]"
      }
    '';
  };

  environment.systemPackages = with pkgs; [
    alacritty
    arandr
    git
    keepassxc
    lxappearance
    mullvad-vpn
    networkmanagerapplet
    nextcloud-client
    pavucontrol
    termite
    vim
    wget
    which

    gvfs

    # yubikey packages
    yubikey-manager-qt
    yubikey-personalization-gui
    yubioath-flutter
  ];

  virtualisation = {
    docker = {
      enable = false;
    };

    podman = {
      enable = true;
      dockerCompat = true;
      defaultNetwork.settings = {
        /* to make networking in docker-compose work */
        dns_enabled = true;
      };
      dockerSocket.enable = true;
    };
    # lxd.enable = true;
    # virtualbox.host.enable = true;
    # virtualbox.host.enableExtensionPack = true;
  };
  # virt-manager
  virtualisation.libvirtd.enable = false;
  programs.virt-manager.enable = false;
  #dconf.settings = {
    #"org/virt-manager/virt-manager/connections" = {
      #autoconnect = ["qemu:///system"];
      #uris = ["qemu:///system"];
    #};
  #};


  programs = {
    # enable zsh globally
    zsh.enable = true;
    gnupg.agent = {
      enable = true;
      enableSSHSupport = true;
      pinentryPackage = pkgs.pinentry-curses;
    };
    thunar = {
      enable = true;
      plugins = with pkgs.xfce; [ thunar-archive-plugin thunar-volman ];
    };
    kdeconnect.enable = true;
  };

  environment.sessionVariables = {
    XKB_DEFAULT_OPTIONS = "caps:escape";
    XKB_DEFAULT_LAYOUT  = "eu";
  };

  # required for i3
  environment.pathsToLink = [ "/libexec" ]; # links /libexec from derivations to /run/current-system/sw

  fonts = {
    enableDefaultPackages = true;
    packages = with pkgs; [
      font-awesome
      nerdfonts
      noto-fonts
      noto-fonts-cjk-sans
      noto-fonts-emoji
      powerline-fonts
      material-icons
    ];
    fontconfig = {
      defaultFonts = {
        monospace = [ "JetBrainsMono Nerd Font" "Noto Color Emoji" "FontAwesome" ];
        sansSerif = [ "JetBrainsMono Nerd Font" "Noto Color Emoji" "FontAwesome" ];
        serif = [ "JetBrainsMono Nerd Font" "Noto Color Emoji" "FontAwesome" ];
      };
    };
  };

  security = {
    # generate login settings
    # ykman otp chalresp --touch --generate 2
    pam.yubico = {
      enable = true;
      # debug = true;
      mode = "challenge-response";
    };
    sudo = {
      package = pkgs.sudo.override { withInsults = true; };
    };

    # rtkit is optional but recommended for pipewire
    rtkit.enable = true;
  };

}