{ lib, config, options, pkgs, modulesPath, ... }:
with lib;
let
  cfg = config.yoda.btrbkBackups;
  daily = {
    preserve-min = "no";
    preserve = "7d 4w 6m";
  };
in
{
  options = {
    yoda.btrbkBackups = mkOption {
      type = types.listOf types.attrs;
      default = [];
      example = [{
        instance = "local-backup-ssd";
        # Optional.
        # Can be used to disable timer.
        #enable = false;
        # Optional.
        # If this is `true` and `volume` starts with `ssh://`, `lz4` transport compression is enabled.
        lz4 = true;
        # Optional.
        #ssh_identity = /root/.ssh/rootNas_ed25519;
        volume = "/jc-data";
        snapshot_dir = "/snap";
        target = "/mnt/backup/snap";
        subvolume = {
          "arch.p1st.de" = {};
        };
      }];
      description = ''
        List containing attrsets.
        Each attrset is used to create one btrbk instance.
      '';
    };
  };

  # lib.forEach:
  #   https://github.com/NixOS/nixpkgs/blob/54f00576aa6139a9d54062d0edc2fb31423f0ffb/lib/lists.nix#L36
  # lib.attrsets.mergeAttrsList:
  #   https://github.com/NixOS/nixpkgs/blob/54f00576aa6139a9d54062d0edc2fb31423f0ffb/lib/attrsets.nix#L786
  config = {
    services.btrbk.instances =
      # Merge list of attr sets into one attr set.
      attrsets.mergeAttrsList (
        forEach
        cfg
        (x:
          # `services.btrbk.instances` template.
          {
            "${x.instance}" = {
              onCalendar = if (x.enable or true) then "12:05" else null;
              settings = {
                timestamp_format = "long";
                stream_compress =  mkIf ((x.lz4 or false) && strings.hasPrefix "ssh://" x.volume) "lz4";
                ssh_identity = mkIf (x?ssh_identity) x.ssh_identity;

                # Create backups.
                target_preserve_min = daily.preserve-min;
                target_preserve = daily.preserve;

                # Don't create or delete snapshots.
                snapshot_preserve_min = "all";
                snapshot_create       = "no";

                volume."${x.volume}" = {
                  snapshot_dir = x.snapshot_dir;
                  target = x.target;
                  subvolume = x.subvolume;
                };
              };
            };
          }
        )
      );
  };
}
