{ config, realPkgs, ... }:

let

  boolToString = bool: if bool then "true" else "false";
  inherit (config.programs.borgmatic) backups;

in
{
  programs.borgmatic = {
    enable = true;
    backups = {
      main = {
        location = {
          sourceDirectories = [ "/my-stuff-to-backup" ];
          repositories = [
            "/mnt/disk1"
            { path = "/mnt/disk2"; }
            {
              path = "/mnt/disk3";
              label = "disk3";
            }
          ];
          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";
          };
        };

        output = {
          extraConfig = {
            color = false;
          };
        };

        hooks = {
          extraConfig = {
            before_actions = [ "echo Starting actions." ];
          };
        };
      };
    };
  };

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

    declare -A expectations

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

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

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

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

    yq=${realPkgs.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 ".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
  '';
}
