{ config, pkgs, ... }:

let
  boolToString = bool: if bool then "true" else "false";
  backups = config.programs.borgmatic.backups;
in {
  config = {
    programs.borgmatic = {
      enable = true;
      backups = {
        main = {
          location = {
            sourceDirectories = [ "/my-stuff-to-backup" ];
            repositories = [ "/mnt/disk1" "/mnt/disk2" ];
            extraConfig = {
              one_file_system = true;
              exclude_patterns = [ "*.swp" ];
            };
          };

          storage = {
            encryptionPasscommand = "fetch-the-password.sh";
            extraConfig = { checkpoint_interval = 200; };
          };

          retention = {
            keepWithin = "14d";
            keepSecondly = 12;
            extraConfig = { prefix = "hostname"; };
          };

          consistency = {
            checks = [
              {
                name = "repository";
                frequency = "2 weeks";
              }
              {
                name = "archives";
                frequency = "4 weeks";
              }
            ];

            extraConfig = { prefix = "hostname"; };
          };
        };
      };
    };

    test.stubs.borgmatic = { };

    nmt.script = ''
      config_file=$TESTED/home-files/.config/borgmatic.d/main.yaml
      assertFileExists $config_file

      declare -A expectations

      expectations[location.source_directories[0]]="${
        builtins.elemAt backups.main.location.sourceDirectories 0
      }"
      expectations[location.repositories[0]]="${
        builtins.elemAt backups.main.location.repositories 0
      }"
      expectations[location.repositories[1]]="${
        builtins.elemAt backups.main.location.repositories 1
      }"
      expectations[location.one_file_system]="${
        boolToString backups.main.location.extraConfig.one_file_system
      }"
      expectations[location.exclude_patterns[0]]="${
        builtins.elemAt backups.main.location.extraConfig.exclude_patterns 0
      }"

      expectations[storage.encryption_passcommand]="${backups.main.storage.encryptionPasscommand}"
      expectations[storage.checkpoint_interval]="${
        toString backups.main.storage.extraConfig.checkpoint_interval
      }"

      expectations[retention.keep_within]="${backups.main.retention.keepWithin}"
      expectations[retention.keep_secondly]="${
        toString backups.main.retention.keepSecondly
      }"
      expectations[retention.prefix]="${backups.main.retention.extraConfig.prefix}"

      expectations[consistency.checks[0].name]="${
        (builtins.elemAt backups.main.consistency.checks 0).name
      }"
      expectations[consistency.checks[0].frequency]="${
        (builtins.elemAt backups.main.consistency.checks 0).frequency
      }"
      expectations[consistency.checks[1].name]="${
        (builtins.elemAt backups.main.consistency.checks 1).name
      }"
      expectations[consistency.checks[1].frequency]="${
        (builtins.elemAt backups.main.consistency.checks 1).frequency
      }"
      expectations[consistency.prefix]="${backups.main.consistency.extraConfig.prefix}"

      yq=${pkgs.yq-go}/bin/yq

      for filter in "''${!expectations[@]}"; do
        expected_value="''${expectations[$filter]}"
        actual_value="$($yq ".$filter" $config_file)"

        if [[ "$actual_value" != "$expected_value" ]]; then
          fail "Expected '$filter' to be '$expected_value' but was '$actual_value'"
        fi
      done

      one_file_system=$($yq ".location.one_file_system" $config_file)
      if [[ $one_file_system != "true" ]]; then
         fail "Expected one_file_system to be true but it was $one_file_system"
      fi
    '';
  };
}
