{ pkgs
, lib
, config
, ... }: with lib; let
  cfg = config.global.fs;
in {
  imports = [
    ./ext4.nix
    ./f2fs.nix
    ./xfs.nix
    ./bcachefs.nix
    ./zfs
  ];

  options.global.fs = {
    type = mkOption {
      type = with types; enum [ "ext4" "f2fs" "xfs" "zfs" "bcachefs" ];
      default = "bcachefs";
      description = "filesystem type to use for persistent state storage";
    };
    store = mkOption {
      type = with types; str;
      default = config.networking.hostName;
      description = "UUID/dataset of nix store backing device";
    };
    esp = {
      enable = mkEnableOption "EFI system partition" // { default = true; };
      uuid = mkOption {
        type = with types; str;
        default = "CAFE-BABE";
        description = "vfat serial number of EFI system partition";
      };
    };
    external = {
      enable = mkEnableOption "external persist filesystem";
      # this wraps the standard fileSystems module
      # since some attrs have to be unconditionally set
      device = mkOption {
        default = null;
        type = with types; nullOr str;
        description = "Location of the device.";
      };
      fsType = mkOption {
        default = "auto";
        type = with types; str;
        description = "Type of the file system.";
      };
      options = mkOption {
        default = [ "defaults" ];
        description = "Options used to mount the file system.";
        type = with types; nonEmptyListOf str;
      };
    };
    cryptsetup = {
      enable = mkEnableOption "full disk encryption device early setup";
      allowDiscards = mkEnableOption "allow discards via device-mapper" // { default = true; };
      bypassWorkqueues = mkEnableOption "bypass dm-crypt's internal workqueues" // { default = true; };
      uuids = mkOption {
        type = with types; attrsOf str;
        description = "device-mapper name to encrypted block device UUID mapping";
      };
    };
  };

  config = {
    fileSystems."/" =
    { device = "rootfs";
      fsType = "tmpfs";
      options = [ "size=2G" "mode=755" ];
    };
    fileSystems."/boot" = mkIf cfg.esp.enable
    { device = "/dev/disk/by-uuid/${cfg.esp.uuid}";
      fsType = "vfat";
    };
    fileSystems."/nix/persist" = mkIf cfg.external.enable
    { inherit (cfg.external) device fsType options;
      neededForBoot = true;
      depends = [ "/nix" ];
    };
    fileSystems."/tmp" =
    { device = "/nix/tmp";
      options = [ "bind" ];
      depends = [ "/nix/tmp" ];
    };

    services.fstrim.enable = mkIf ((cfg.type == "ext4") || (cfg.type == "xfs")) true;

    boot.initrd.luks.devices = mkIf cfg.cryptsetup.enable (
    mapAttrs' (name: uuid: nameValuePair "luks-${name}" {
      inherit (cfg.cryptsetup) allowDiscards bypassWorkqueues;
      device = "/dev/disk/by-uuid/${uuid}";
    }) cfg.cryptsetup.uuids);

    environment.persistence."/nix/persist/fhs".files = [ {
      file = "/var/lib/private/mode";
      parentDirectory.mode = "0700";
    } ];
  };
}
