package middleware

import (
	"testing"

	"security-center-backend/internal/model"
	"security-center-backend/internal/service/audit"
	"security-center-backend/internal/service/jwt"
)

func newAttributionEntry() *audit.Entry {
	return &audit.Entry{
		ActorType: "system",
		Metadata:  model.JSONB{},
	}
}

func TestApplyActorAttributionAgentClaims(t *testing.T) {
	entry := newAttributionEntry()
	claims := &jwt.Claims{
		UserID:          42,
		Email:           "owner@example.com",
		ActorType:       "agent",
		AgentID:         7,
		AgentName:       "sec-bot",
		DelegatedUserID: 42,
	}

	applyActorAttribution(entry, claims, "agent")

	if entry.ActorType != "agent" {
		t.Errorf("ActorType = %q, want %q", entry.ActorType, "agent")
	}
	if entry.UserID == nil || *entry.UserID != 42 {
		t.Errorf("UserID = %v, want 42", entry.UserID)
	}
	if entry.ActorUserID == nil || *entry.ActorUserID != 42 {
		t.Errorf("ActorUserID = %v, want 42", entry.ActorUserID)
	}
	if entry.ActorEmail != "owner@example.com" {
		t.Errorf("ActorEmail = %q, want %q", entry.ActorEmail, "owner@example.com")
	}

	wantMeta := map[string]interface{}{
		"agent_id":          uint64(7),
		"agent_name":        "sec-bot",
		"delegated_user_id": uint64(42),
		"auth_method":       "agent",
	}
	for key, want := range wantMeta {
		got, ok := entry.Metadata[key]
		if !ok {
			t.Errorf("Metadata missing key %q", key)
			continue
		}
		if got != want {
			t.Errorf("Metadata[%q] = %v, want %v", key, got, want)
		}
	}
}

func TestApplyActorAttributionUserClaims(t *testing.T) {
	entry := newAttributionEntry()
	claims := &jwt.Claims{
		UserID: 9,
		Email:  "user@example.com",
	}

	applyActorAttribution(entry, claims, "jwt")

	if entry.ActorType != "user" {
		t.Errorf("ActorType = %q, want %q", entry.ActorType, "user")
	}
	if entry.UserID == nil || *entry.UserID != 9 {
		t.Errorf("UserID = %v, want 9", entry.UserID)
	}
	if entry.ActorEmail != "user@example.com" {
		t.Errorf("ActorEmail = %q, want %q", entry.ActorEmail, "user@example.com")
	}
	for _, key := range []string{"agent_id", "agent_name", "delegated_user_id", "auth_method"} {
		if _, ok := entry.Metadata[key]; ok {
			t.Errorf("Metadata should not contain key %q for user claims", key)
		}
	}
}

func TestApplyActorAttributionNilClaims(t *testing.T) {
	entry := newAttributionEntry()

	applyActorAttribution(entry, nil, "")

	if entry.ActorType != "system" {
		t.Errorf("ActorType = %q, want %q", entry.ActorType, "system")
	}
	if entry.UserID != nil || entry.ActorUserID != nil || entry.ActorEmail != "" {
		t.Errorf("expected no actor attribution, got UserID=%v ActorUserID=%v ActorEmail=%q",
			entry.UserID, entry.ActorUserID, entry.ActorEmail)
	}
	if len(entry.Metadata) != 0 {
		t.Errorf("Metadata = %v, want empty", entry.Metadata)
	}
}
