package accessruleaudit

import (
	"testing"
	"time"
)

func TestVerifyMigrationAcceptsMatchingArchiveAndUnchangedDeny(t *testing.T) {
	before := auditSnapshot(3, "allow-before", 2, "deny-before", nil)
	after := auditSnapshot(0, "", 2, "deny-before", &ArchiveManifest{
		MigrationBatch:     MigrationBatch,
		ManifestAllowCount: 3,
		ManifestAllowSHA:   sha256Hex("allow-before"),
		ArchivedAllowCount: 3,
		ArchivedAllowSHA:   sha256Hex("allow-before"),
		ManifestDenyCount:  2,
		ManifestDenySHA:    sha256Hex("deny-before"),
		Consistent:         true,
	})
	if err := VerifyMigration(before, after); err != nil {
		t.Fatalf("verify matching migration: %v", err)
	}
}

func TestVerifyMigrationRejectsChangedDenyOrMissingArchive(t *testing.T) {
	before := auditSnapshot(1, "allow", 1, "deny", nil)
	withoutArchive := auditSnapshot(0, "", 1, "deny", nil)
	if err := VerifyMigration(before, withoutArchive); err == nil {
		t.Fatal("missing archive must fail verification")
	}
	changedDeny := auditSnapshot(0, "", 1, "changed-deny", &ArchiveManifest{
		MigrationBatch:     MigrationBatch,
		ManifestAllowCount: 1,
		ManifestAllowSHA:   sha256Hex("allow"),
		ArchivedAllowCount: 1,
		ArchivedAllowSHA:   sha256Hex("allow"),
		ManifestDenyCount:  1,
		ManifestDenySHA:    sha256Hex("deny"),
		Consistent:         true,
	})
	if err := VerifyMigration(before, changedDeny); err == nil {
		t.Fatal("changed deny hash must fail verification")
	}
}

func auditSnapshot(allowCount int64, allowSeed string, denyCount int64, denySeed string, archive *ArchiveManifest) Snapshot {
	counts := make([]RuleCount, 0, 2)
	if allowCount > 0 {
		counts = append(counts, RuleCount{SubjectType: "api_key", Effect: "allow", ResourceType: "platform_model", Status: "active", Count: allowCount})
	}
	if denyCount > 0 {
		counts = append(counts, RuleCount{SubjectType: "api_key", Effect: "deny", ResourceType: "platform_model", Status: "active", Count: denyCount})
	}
	return Snapshot{
		SchemaVersion: SchemaVersion,
		GeneratedAt:   time.Date(2026, 8, 3, 0, 0, 0, 0, time.UTC),
		SecretSafe:    true,
		Live: RuleSet{
			Total:       allowCount + denyCount,
			SHA256:      sha256Hex("all-" + allowSeed + "-" + denySeed),
			AllowCount:  allowCount,
			AllowSHA256: sha256Hex(allowSeed),
			DenyCount:   denyCount,
			DenySHA256:  sha256Hex(denySeed),
			Counts:      counts,
		},
		Archive: archive,
	}
}
