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

let
  alias_nix_pin_revision = pkgs.writeShellScriptBin "nix-pin-revision" ''
    # Usage: nix-pin-revision nixpkgs 'github:NixOS/nixpkgs/00c21e4c93d963c50d4c0c89bfa84ed6e0694df2'
    exec nix flake lock --override-input "''${@}"
  '';
in
{
  imports = [
    ./roles/2ship2harkinian
    ./roles/alacritty
    ./roles/amd_s2idle
    ./roles/android
    ./roles/ansible
    ./roles/ares
    ./roles/base
    ./roles/bluetooth
    ./roles/boot
    ./roles/build_in_ram
    ./roles/chromecast
    ./roles/chromium
    ./roles/d2
    ./roles/direnv
    ./roles/disko
    ./roles/distributed_build
    ./roles/doas
    ./roles/docker
    ./roles/dont_use_substituters
    ./roles/ecc
    ./roles/emacs
    ./roles/emulate_isa
    ./roles/esim
    ./roles/firefox
    ./roles/firewall
    ./roles/flux
    ./roles/fonts
    ./roles/gcloud
    ./roles/git
    ./roles/global_options
    ./roles/gnome_keyring
    ./roles/gnuplot
    ./roles/gpg
    ./roles/graphics
    ./roles/graphviz
    ./roles/hydra
    ./roles/image_based_appliance
    ./roles/iso
    ./roles/iso_mount
    ./roles/jujutsu
    ./roles/kanshi
    ./roles/kodi
    ./roles/kubernetes
    ./roles/latex
    ./roles/launch_keyboard
    ./roles/lvfs
    ./roles/media
    ./roles/memtest86
    ./roles/minimal_base
    ./roles/network
    ./roles/nix_index
    ./roles/nix_repl
    ./roles/nix_worker
    ./roles/nixdev
    ./roles/nvme
    ./roles/openpgp_card_tools
    ./roles/optimized_build
    ./roles/pcsx2
    ./roles/podman
    ./roles/postgresql_client
    ./roles/python
    ./roles/qemu
    ./roles/recovery
    ./roles/reset
    ./roles/rpcs3
    ./roles/rust
    ./roles/sequoia
    ./roles/shadps4
    ./roles/shikane
    ./roles/shipwright
    ./roles/sm64ex
    ./roles/sops
    ./roles/sound
    ./roles/spaghettikart
    ./roles/ssh
    ./roles/sshd
    ./roles/steam
    ./roles/steam_run_free
    ./roles/sway
    ./roles/tekton
    ./roles/terraform
    ./roles/thunderbolt
    ./roles/user
    ./roles/uutils
    ./roles/vnc_client
    ./roles/vscode
    ./roles/wasm
    ./roles/waybar
    ./roles/webcam
    ./roles/wine
    ./roles/wireguard
    ./roles/yubikey
    ./roles/zfs
    ./roles/zrepl
    ./roles/zsh
    ./util/install_files
    ./util/unfree_polyfill
  ];

  config = {
    nix.settings.experimental-features = [
      "nix-command"
      "flakes"
      "ca-derivations"
      # "blake3-hashes"
      # "git-hashing"
    ];
    nix.settings.trusted-users = [ "@wheel" ];
    nix.settings.connect-timeout = 5;
    nix.settings.min-free = 128000000;
    nix.settings.max-free = 1000000000;
    nix.settings.fallback = true;
    nix.settings.warn-dirty = false;
    nix.settings.fsync-metadata = true;
    # Ensure store paths are durably written to disk before registering the paths so a crash mid-build does not leave us in a corrupted state.
    nix.settings.fsync-store-paths = true;

    hardware.enableRedistributableFirmware = true;

    # Keep outputs so we can build offline.
    nix.settings.keep-outputs = true;
    nix.settings.keep-derivations = true;

    # Automatic garbage collection
    nix.gc = lib.mkIf (!config.me.buildingPortable) {
      # Runs nix-collect-garbage --delete-older-than 5d
      automatic = true;
      persistent = true;
      dates = "monthly";
      # randomizedDelaySec = "14m";
      options = "--delete-older-than 30d";
    };
    nix.settings.auto-optimise-store = !config.me.buildingPortable;

    environment.systemPackages = [
      alias_nix_pin_revision
    ];

    environment.persistence."/persist" = lib.mkIf (config.me.mountPersistence) {
      hideMounts = true;
      directories = [
        "/var/lib/nixos" # Contains user information (uids/gids)
        "/var/lib/systemd" # Systemd state directory for random seed, persistent timers, core dumps, persist hardware state like backlight and rfkill
        "/var/log/journal" # Logs, alternatively set `services.journald.storage = "volatile";` to write to /run/log/journal
      ];
      files = [
        "/etc/machine-id" # Systemd unique machine id "otherwise, the system journal may fail to list earlier boots, etc"
      ];
    };

    # Write a list of the currently installed packages to /etc/current-system-packages
    # environment.etc."current-system-packages".text =
    #   let
    #     packages = builtins.map (p: "${p.name}") config.environment.systemPackages;
    #     sortedUnique = builtins.sort builtins.lessThan (lib.unique packages);
    #     formatted = builtins.concatStringsSep "\n" sortedUnique;
    #   in
    #   formatted;

    # nixpkgs.overlays = [
    #   (final: prev: {
    #     foot = throw "foo";
    #   })
    # ];

    nixpkgs.overlays =
      let
        disableTests = (
          # Example: (disableTests "coreutils")
          package_name:
          (final: prev: {
            "${package_name}" = prev."${package_name}".overrideAttrs (old: {
              doCheck = false;
              doInstallCheck = false;
            });
          })
        );
        disableTestsPython = (
          # Example: (disableTestsPython "scipy")
          package_name:
          (final: prev: {
            pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
              (python-final: python-prev: {
                "${package_name}" = python-prev."${package_name}".overridePythonAttrs (oldAttrs: {
                  doCheck = false;
                });
              })
            ];
          })
        );
        disableOptimizations = (
          # Example: (disableOptimizations "coreutils")
          package_name:
          (final: prev: {
            "${package_name}" = final.unoptimized."${package_name}";
          })
        );
        disableOptimizationsScope = (
          # Example: (disableOptimizationsScope "kdePackages" "qtbase")
          scope: package_name:
          (final: prev: {
            "${scope}" = prev."${scope}".overrideScope (
              scopeFinal: scopePrev: {
                "${package_name}" = final.unoptimized."${scope}"."${package_name}";
              }
            );
          })
        );
        disableOptimizationsPython3 = (
          # Example: (disableOptimizationsPython3 "scipy")
          package_name:
          (final: prev: {
            python3Packages = prev.python3Packages.override {
              overrides = python-final: python-prev: {
                "${package_name}" = final.unoptimized.python3.pkgs."${package_name}";
              };
            };
          })
        );
      in
      [
        (disableTests "coreutils")
        (disableTests "coreutils-full")
        (disableTests "deno") # Tests use too much disk space
        (disableTests "libuv")
        (final: prev: {
          inherit (final.unoptimized)
            libtpms
            libjxl
            ddrescueview
            deno
            mesa
            ;
        })
        (disableOptimizationsPython3 "scipy")
        # Works but probably sets python2's scipy to be python3:
        #
        # (final: prev: {
        #   pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
        #     (python-final: python-prev: {
        #       scipy = final.unoptimized.python3Packages.scipy;
        #     })
        #   ];
        # })
      ];

    # This option defines the first version of NixOS you have installed on this particular machine,
    # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
    #
    # Most users should NEVER change this value after the initial install, for any reason,
    # even if you've upgraded your system to a new NixOS release.
    #
    # This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
    # so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
    # to actually do that.
    #
    # This value being lower than the current NixOS release does NOT mean your system is
    # out of date, out of support, or vulnerable.
    #
    # Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
    # and migrated your data accordingly.
    #
    # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
    system.stateVersion = "24.11"; # Did you read the comment?
  };
}
