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

with lib;

let
  cfg = config.sydnix.impermanence;
in {
  imports = [
    ./impermanence/rollback.nix
  ];

  options = {
    sydnix.impermanence = {
      enable = mkEnableOption "Impermanence";

      directories = mkOption {
        type = with types; listOf anything;
        default = [];
      };

      files = mkOption {
        type = with types; listOf anything;
        default = [];
      };

      persistDirectory = mkOption {
        default = "/persist";
        type = types.str;
        description = ''
          The directory in which persistent files live.
        '';
      };

      persistGroupName = mkOption {
        default = "persist";
        type = types.str;
        description = ''
          Name of the group whose members have access to the persist directory.
        '';
      };

      cache = {
        directories = mkOption {
          description = ''
            While functionally identical to `directories` (at the moment),
            `cache.directories` carries additional semantics: these directories
            /can/ be erased, but typically /shouldn't/ be.
          '';
          default = [];
          type = types.listOf types.anything;
        };

        files = mkOption {
          description = ''
            While functionally identical to `files` (at the moment),
            `cache.files` carries additional semantics: these files /can/ be
            erased, but typically /shouldn't/ be.
          '';
          default = [];
          type = types.listOf types.anything;
        };
      };
    };
  };

  config = mkIf cfg.enable {
    # Create a group called `cfg.persistGroupName`
    users.groups.${cfg.persistGroupName} = {
      name = cfg.persistGroupName;
    };

    # Permit members of `cfg.persistGroupName` to read, write, and execute
    # /persist.
    systemd.tmpfiles.settings."10-persist" = {
      ${cfg.persistDirectory} = {
        z.group = cfg.persistGroupName;
        z.mode = "2775";
      };
      "${cfg.persistDirectory}/home" = {
        z.group = "users";
        z.mode = "2775";
      };
      "${cfg.persistDirectory}/vault" = {
        z.group = "users";
        z.mode = "2775";
      };
      "${cfg.persistDirectory}/vault/root" = {
        z.group = "root";
        z.mode = "2775";
      };
    };

    # TODO: Move this somewhere else.
    programs.fuse.userAllowOther = true;

    environment.persistence."${cfg.persistDirectory}/root" = {
      directories = cfg.directories ++ cfg.cache.directories;
      files = cfg.files ++ cfg.cache.files;
    };
  };
}
