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

  cfg = config.systemd.shutdownRamfs;

  ramfsContents = pkgs.writeText "shutdown-ramfs-contents.json" (builtins.toJSON cfg.storePaths);

in {
  options.systemd.shutdownRamfs = {
    enable = lib.mkEnableOption "pivoting back to an initramfs for shutdown" // { default = true; };
    contents = lib.mkOption {
      description = "Set of files that have to be linked into the shutdown ramfs";
      example = lib.literalExpression ''
        {
          "/lib/systemd/system-shutdown/zpool-sync-shutdown".source = writeShellScript "zpool" "exec ''${zfs}/bin/zpool sync"
        }
      '';
      type = utils.systemdUtils.types.initrdContents;
    };

    storePaths = lib.mkOption {
      description = ''
        Store paths to copy into the shutdown ramfs as well.
      '';
      type = utils.systemdUtils.types.initrdStorePath;
      default = [];
    };
  };

  config = lib.mkIf cfg.enable {
    systemd.shutdownRamfs.contents = {
      "/shutdown".source = "${config.systemd.package}/lib/systemd/systemd-shutdown";
      "/etc/initrd-release".source = config.environment.etc.os-release.source;
      "/etc/os-release".source = config.environment.etc.os-release.source;
    };
    systemd.shutdownRamfs.storePaths = [pkgs.runtimeShell "${pkgs.coreutils}/bin"]
      ++ map (c: builtins.removeAttrs c ["text"]) (builtins.attrValues cfg.contents);

    systemd.mounts = [{
      what = "tmpfs";
      where = "/run/initramfs";
      type = "tmpfs";
    }];

    systemd.services.generate-shutdown-ramfs = {
      description = "Generate shutdown ramfs";
      wantedBy = [ "shutdown.target" ];
      before = [ "shutdown.target" ];
      unitConfig = {
        DefaultDependencies = false;
        RequiresMountsFor = "/run/initramfs";
        ConditionFileIsExecutable = [
          "!/run/initramfs/shutdown"
        ];
      };

      serviceConfig = {
        Type = "oneshot";
        ProtectSystem = "strict";
        ReadWritePaths = "/run/initramfs";
        ExecStart = "${pkgs.makeInitrdNGTool}/bin/make-initrd-ng ${ramfsContents} /run/initramfs";
      };
    };
  };
}
