package reconcile

import (
	"testing"

	"gitea.dooplex.hu/admin/felhom-agent/internal/authz"
)

func TestClassify_BenignClasses(t *testing.T) {
	for _, c := range []OpClass{ClassStart, ClassStop, ClassSetConfig, ClassCreate, ClassRestart} {
		if got := Classify(c, Provenance{}); got != Benign {
			t.Errorf("Classify(%s) = %s, want benign", c, got)
		}
	}
}

func TestClassify_DestructiveClassesNeedSignature(t *testing.T) {
	for _, c := range []OpClass{ClassGuestDestroy, ClassStorageWipe, ClassRestoreOverwrite, ClassDecommission, ClassKeyRotation} {
		if got := Classify(c, Provenance{}); got != Destructive {
			t.Errorf("Classify(%s) = %s, want destructive", c, got)
		}
	}
}

func TestClassify_InternalProvenanceMakesDestroyBenign(t *testing.T) {
	// Same-transaction create → compensating rollback is benign (§10).
	if got := Classify(ClassGuestDestroy, Provenance{SameTxnCreated: true}); got != Benign {
		t.Errorf("same-txn destroy = %s, want benign", got)
	}
	// Agent-tagged scratch teardown is benign (§8).
	if got := Classify(ClassGuestDestroy, Provenance{AgentTaggedScratch: true}); got != Benign {
		t.Errorf("scratch destroy = %s, want benign", got)
	}
}

func TestClassify_KeyRotationAlwaysDestructive(t *testing.T) {
	// Even with internal provenance, key-rotation stays signed (role-scoping decides
	// which key) — provenance flags don't apply to it.
	if got := Classify(ClassKeyRotation, Provenance{SameTxnCreated: true, AgentTaggedScratch: true}); got != Destructive {
		t.Errorf("key_rotation = %s, want destructive", got)
	}
}

func TestClassify_UnknownClassFailsSafe(t *testing.T) {
	if got := Classify(OpClass("totally_unknown_op"), Provenance{}); got != Destructive {
		t.Errorf("unknown class = %s, want destructive (fail-safe)", got)
	}
}

func TestRoleAuthorizes(t *testing.T) {
	op := authz.RoleOperational
	rec := authz.RoleRecovery
	cases := []struct {
		role  authz.KeyRole
		class OpClass
		want  bool
	}{
		{op, ClassGuestDestroy, true},   // operational does ordinary destructive
		{op, ClassDecommission, true},   //
		{op, ClassKeyRotation, true},    // operational does planned rotation
		{rec, ClassGuestDestroy, false}, // recovery may NOT do ordinary destructive
		{rec, ClassStorageWipe, false},  //
		{rec, ClassKeyRotation, true},   // recovery authorizes ONLY rotation
	}
	for _, c := range cases {
		if got := roleAuthorizes(c.role, c.class); got != c.want {
			t.Errorf("roleAuthorizes(%s, %s) = %v, want %v", c.role, c.class, got, c.want)
		}
	}
}
