# Configure restic backups to S3-compatible storage, in our case
# GleSYS object storage.
#
# Conventions:
# - restic's cache lives in /var/backup/restic/cache
# - repository password lives in /var/backup/restic/secret
# - object storage credentials in /var/backup/restic/glesys-key
{ config, lib, pkgs, ... }:

let
  cfg = config.services.depot.restic;
  description = "Restic backups to GleSYS";
  mkStringOption = default: lib.mkOption {
    inherit default;
    type = lib.types.str;
  };
in
{
  options.services.depot.restic = {
    enable = lib.mkEnableOption description;
    bucketEndpoint = mkStringOption "objects.dc-sto1.glesys.net";
    bucketName = mkStringOption "aged-resonance";
    bucketCredentials = mkStringOption "/var/backup/restic/glesys-key";
    repository = mkStringOption config.networking.hostName;
    interval = mkStringOption "hourly";

    paths = with lib; mkOption {
      description = "Directories that should be backed up";
      type = types.listOf types.str;
    };

    exclude = with lib; mkOption {
      description = "Files that should be excluded from backups";
      type = types.listOf types.str;
    };
  };

  config = lib.mkIf cfg.enable {
    systemd.services.restic = {
      description = "Backups to GleSYS";

      script = "${pkgs.restic}/bin/restic backup ${lib.concatStringsSep " " cfg.paths}";

      environment = {
        RESTIC_REPOSITORY = "s3:${cfg.bucketEndpoint}/${cfg.bucketName}/${cfg.repository}";
        AWS_SHARED_CREDENTIALS_FILE = cfg.bucketCredentials;
        RESTIC_PASSWORD_FILE = "/var/backup/restic/secret";
        RESTIC_CACHE_DIR = "/var/backup/restic/cache";

        RESTIC_EXCLUDE_FILE =
          builtins.toFile "exclude-files" (lib.concatStringsSep "\n" cfg.exclude);
      };
    };

    systemd.timers.restic = {
      wantedBy = [ "multi-user.target" ];
      timerConfig.OnCalendar = cfg.interval;
    };

    environment.systemPackages = [ pkgs.restic ];
  };
}