package main

import (
	"reflect"
	"testing"
)

func TestParseBackupStatus(t *testing.T) {
	line := `{"message_type":"status","percent_done":0.5,"total_bytes":1000,"bytes_done":500,"total_files":10,"files_done":5}`
	want := backupStatus{Type: "status", Percent: 0.5, Total: 1000, Bytes: 500, TotalFiles: 10, FilesDone: 5}
	if got, ok := parseBackupStatus(line); !ok || !reflect.DeepEqual(got, want) {
		t.Fatalf("parseBackupStatus() = %#v, %v; want %#v, true", got, ok, want)
	}
	if _, ok := parseBackupStatus(`{"message_type":"summary"}`); ok {
		t.Fatal("expected summary message to be ignored")
	}
	if _, ok := parseBackupStatus("not json"); ok {
		t.Fatal("expected malformed status to be ignored")
	}
}

func TestBackupArgs(t *testing.T) {
	prof := Profile{
		Backend:   "restic",
		RetryLock: "30s",
		Backup: Backup{
			Args:          []string{"--exclude", "*.tmp"},
			ArgsScheduled: []string{"--tag", "scheduled"},
			Paths:         []string{"/documents", "/photos"},
		},
	}
	want := []string{"backup", "--json", "--retry-lock", "30s", "--exclude", "*.tmp", "--tag", "scheduled", "/documents", "/photos"}
	if got := backupArgs(prof, true, "--json"); !reflect.DeepEqual(got, want) {
		t.Fatalf("backupArgs() = %#v, want %#v", got, want)
	}

	prof.Backend = "rustic"
	want = []string{"backup", "--json-progress", "--exclude", "*.tmp", "/documents", "/photos"}
	if got := backupArgs(prof, false, "--json-progress"); !reflect.DeepEqual(got, want) {
		t.Fatalf("rustic backupArgs() = %#v, want %#v", got, want)
	}
}

func TestRunScheduledOperations(t *testing.T) {
	prof := Profile{Schedule: Schedule{Prune: true, Check: true}, Prune: OperationOptions{Args: []string{"--keep-last", "4"}}}
	var ran []string
	failed, msg := runScheduledOperations(prof, nil,
		func() (bool, string) { ran = append(ran, "backup"); return false, "backup failed" },
		func() (bool, string) { ran = append(ran, "prune"); return true, "" },
		func() (bool, string) { ran = append(ran, "check"); return true, "" },
	)
	if !failed || msg != "backup failed" || !reflect.DeepEqual(ran, []string{"backup"}) {
		t.Fatalf("backup failure: failed=%v msg=%q ran=%v", failed, msg, ran)
	}

	ran = nil
	disabled := false
	prof.Schedule.Backup = &disabled
	failed, msg = runScheduledOperations(prof, nil,
		func() (bool, string) { ran = append(ran, "backup"); return true, "" },
		func() (bool, string) { ran = append(ran, "prune"); return false, "prune failed" },
		func() (bool, string) { ran = append(ran, "check"); return false, "check failed" },
	)
	if !failed || msg != "prune failed" || !reflect.DeepEqual(ran, []string{"prune", "check"}) {
		t.Fatalf("maintenance failure: failed=%v msg=%q ran=%v", failed, msg, ran)
	}
}
