{
  lib,
  pkgs,
  config,
  ...
}:
let
  cfg = config.services.barman;
  iniFormat = pkgs.formats.ini { };
  defaultUser = "barman";
  defaultHome = "/var/lib/barman";

  runtimeInputs = with pkgs; [
    cfg.package
    bash
    bzip2
    gzip
    lz4
    pigz
    postgresql
    zstd
  ];

  barmanWrapper = pkgs.writeShellApplication {
    name = "bm";

    inherit runtimeInputs;

    text = ''
      sudo --set-home --user ${cfg.settings.barman.barman_user} -- ${cfg.package}/bin/barman "$@"
    '';
  };
in
{
  options.services.barman = {
    enable = lib.mkEnableOption "barman";
    package = lib.mkPackageOption pkgs "barman" { };

    settings = lib.mkOption {
      description = "Global barman configuration that goes in the `[barman]` section of `barman.conf`";
      type = lib.types.submodule { freeformType = iniFormat.type; };
      example = {
        barman_user = defaultUser;
        barman_home = defaultHome;
        log_file = "/var/log/barman/barman.log";
      };
    };

    servers = lib.mkOption {
      description = "Server configurations";
      type = lib.types.submodule { freeformType = iniFormat.type; };
      default = { };
    };

    # passwordsFile = lib.mkOption {
    #   description = "Path to the PostgreSQL password file. See [the documentation](https://www.postgresql.org/docs/current/libpq-pgpass.html) for the format.";
    #   type = lib.types.path;
    #   default = null;
    # };
  };

  config = lib.mkIf cfg.enable {
    services.barman.settings = {
      barman = {
        barman_user = lib.mkDefault defaultUser;
        barman_home = lib.mkDefault defaultHome;
        compression = lib.mkDefault "pigz";
        backup_compression = lib.mkDefault "zstd";
      };
    };

    users.users."${cfg.settings.barman.barman_user}" = {
      isSystemUser = true;
      home = cfg.settings.barman.barman_home;
      createHome = true;
      group = cfg.settings.barman.barman_user;
    };

    users.groups."${cfg.settings.barman.barman_user}" = { };

    environment = {
      etc =
        {
          "barman.conf" = {
            user = cfg.settings.barman.barman_user;
            source = iniFormat.generate "barman.conf" cfg.settings;
          };
        }
        // (lib.mapAttrs' (name: serverConfig: {
          name = "barman.d/${name}.conf";
          value = {
            user = cfg.settings.barman.barman_user;
            source = iniFormat.generate "${name}.conf" { "${name}" = serverConfig; };
          };
        }) cfg.servers);

      systemPackages = [
        cfg.package
        barmanWrapper
      ];
    };
    systemd = {
      timers.barman = {
        description = "Update timer for barman";
        partOf = [ "barman.service" ];
        wantedBy = [ "timers.target" ];
        timerConfig = {
          OnCalendar = "*:*:0";
        };
      };

      services.barman = {
        description = "Run barman maintenance tasks";
        path = runtimeInputs;
        environment = {
          HOME = cfg.settings.barman.barman_home;
        };

        serviceConfig = {
          Type = "oneshot";
          User = cfg.settings.barman.barman_user;
          ExecStart = "${cfg.package}/bin/barman cron";
          WorkingDirectory = cfg.settings.barman.barman_home;
        };
      };
    };

  };
}