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

with lib;
let
  # Available to all users on the system. Keep it minimal.
  global-packages = with pkgs; [
    bind
    cryptsetup
    git
    heimdal
    mosh
    openssh_gssapi
    tldr
    vim
    wget
  ];

  import-paths = [
    ./build
    ./host
    ./user
  ];

in {

  imports = let
    is-regular-file = filename: type: type == "regular" || type == "link";
    regular-files = path:
      attrNames (filterAttrs is-regular-file (builtins.readDir path));
    is-nix-file = filename: (builtins.match "^(.+)\.nix$" filename) != null;
    nix-files = path:
      map
        (file: path + "/${file}")
        (filter is-nix-file (regular-files path));
  in concatMap nix-files import-paths;

  config = {
    environment = {
      etc.nixos-live.source = ../../.;

      systemPackages = global-packages;
    };

    system.autoUpgrade.enable = false;

    nix = {
      package = pkgs.nixFlakes;
      extraOptions = ''
      experimental-features = nix-command flakes
    '';
    };

    nixpkgs.config.allowUnfree = true;
    security.acme.acceptTerms = true;
    hardware.enableRedistributableFirmware = true;

    krb5 = {
      enable = true;

      appdefaults = {
        forwardable = true;
        proxiable = true;
        encrypt = true;
        forward = true;
      };

      libdefaults = {
        allow_weak_crypto = true;
        dns_lookup_kdc = true;
        dns_lookup_realm = true;
        forwardable = true;
        proxiable = true;
      };

      kerberos = pkgs.heimdalFull;
    };

    services = {
      openssh = {
        enable = true;
        startWhenNeeded = true;
        useDns = true;
        permitRootLogin = "prohibit-password";
        extraConfig = ''
        GSSAPIAuthentication yes
        GSSAPICleanupCredentials yes
        GSSAPIKeyExchange yes
        GSSAPIStoreCredentialsOnRekey yes
      '';
      };

      fail2ban = let
        domain-name = config.fudo.hosts.${config.instance.hostname}.domain;
      in {
        enable = config.networking.firewall.enable;
        bantime-increment.enable = true;
      };

      xserver = {
        layout = "us";
        xkbVariant = "dvp";
        xkbOptions = "ctrl:nocaps";
      };

      # pcscd.enable = true;
      # udev.packages = with pkgs; [ yubikey-personalization ];
    };

    networking.firewall = {
      # Allow mosh connections if the firewall is enabled
      allowedUDPPortRanges = [{
        from = 60000;
        to = 60100;
      }];
    };

    console.useXkbConfig = true;

    i18n.defaultLocale = "en_US.UTF-8";

    programs = {
      mosh.enable = true;

      bash.enableCompletion = true;

      fish.enable = true;

      gnupg.agent = {
        enable = true;
        # enableSSHSupport = true;
        # pinentryFlavor = if cfg.enable-gui then "gnome3" else "curses";
      };

      ssh = {
        startAgent = true;

        package = pkgs.openssh_gssapi;

        extraConfig = ''
          GSSAPIAuthentication yes
          GSSAPIDelegateCredentials yes
        '';
      };
    };

    security.pam = {
      enableSSHAgentAuth = true;

      services = {
        sshd = {
          makeHomeDir = true;
          sshAgentAuth = true;
          # This isn't supposed to ask for a code unless ~/.google_authenticator exists...but it does
          # googleAuthenticator.enable = true;
        };
      };
    };

    home-manager = {
      useGlobalPkgs = true;
    };
  };
}