package agent

import (
	"context"
	"strings"
	"testing"
)

// stubPersonas, testte tek kullanıcıya profil veren sahte kaynaktır.
type stubPersonas struct {
	byUser map[string][]Persona
	calls  int
}

func (s *stubPersonas) ActiveProfiles(_ context.Context, userID string) []Persona {
	s.calls++
	return s.byUser[userID]
}

func TestAgent_PersonaProfilesIstemeGirer(t *testing.T) {
	src := &stubPersonas{byUser: map[string][]Persona{
		"mert": {{Name: "Proje Yöneticisi", Role: "proje yöneticisidir", Instructions: "Eksiksiz bilgi al."}},
	}}
	a := &Agent{}
	a.SetPersonas(src)

	got := a.PersonaProfiles(context.Background(), "mert")
	if len(got) != 1 || got[0].Name != "Proje Yöneticisi" {
		t.Fatalf("Mert'in profili okunmalı, %v", got)
	}
	if len(a.PersonaProfiles(context.Background(), "ayse")) != 0 {
		t.Fatal("profili olmayan kullanıcıya profil dönmemeli")
	}
	if src.calls != 2 {
		t.Fatalf("kaynak her seferinde okunmalı (her tur taze), %d", src.calls)
	}
}

func TestAgent_ProfilYoksaIstemDegismez(t *testing.T) {
	// Bağlanmamış ajan (profil kaynağı nil) çalışmaya devam etmeli.
	a := &Agent{}
	if a.PersonaProfiles(context.Background(), "mert") != nil {
		t.Fatal("kaynak yokken profil dönmemeli")
	}
	// Bağlanmış ama profili olmayan kullanıcı da boş döner.
	a.SetPersonas(&stubPersonas{})
	if len(a.PersonaProfiles(context.Background(), "mert")) != 0 {
		t.Fatal("atanmamış kullanıcıya profil dönmemeli")
	}
	// SetPersonas(nil) panik yaratmamalı.
	a.SetPersonas(nil)
	if a.PersonaProfiles(context.Background(), "mert") != nil {
		t.Fatal("nil kaynak profil dönmemeli")
	}
}

func TestAgent_ProfilSadeceO_kullaniciyaGirer(t *testing.T) {
	// ASIL KURAL: profil KULLANICIYA ÖZELDİR. Başka bir kullanıcıyla konuşulduğunda
	// o kurallar isteme GİRMEMELİ — aksi hâlde Mert'e yazılan "proje yöneticisi"
	// kuralı Ayşe'nin sohbetinde de geçerli olurdu (gizlilik + yanlış davranış).
	src := &stubPersonas{byUser: map[string][]Persona{
		"mert": {{Name: "Proje Yöneticisi", Instructions: "Sadece Mert için."}},
	}}
	a := &Agent{}
	a.SetPersonas(src)

	mertPrompt := a.systemPromptFor(context.Background(), "mert", false, turnPlan{userID: "mert"})
	if !strings.Contains(mertPrompt, "Sadece Mert için.") {
		t.Fatalf("Mert'in isteminde profil olmalı:\n%s", mertPrompt)
	}

	aysePrompt := a.systemPromptFor(context.Background(), "ayse", false, turnPlan{userID: "ayse"})
	if strings.Contains(aysePrompt, "Sadece Mert için.") {
		t.Fatalf("başka kullanıcının istemine profil SIZDI:\n%s", aysePrompt)
	}
	if strings.Contains(aysePrompt, "Proje Yöneticisi") {
		t.Fatalf("Ayşe'nin isteminde Mert'in profili görünmemeli:\n%s", aysePrompt)
	}
}

func TestAgent_ProfilGuvenlikKurallarindanSonraGirer(t *testing.T) {
	// Profil bölümü, "Rules" bölümünden SONRA olmalı: güvenlik kuralları ezilemez.
	a := &Agent{}
	a.SetPersonas(&stubPersonas{byUser: map[string][]Persona{
		"mert": {{Name: "P", Instructions: "K."}},
	}})
	sys := a.systemPromptFor(context.Background(), "mert", false, turnPlan{userID: "mert"})
	iProfile := strings.Index(sys, "Kullanıcı profilleri")
	if iProfile < 0 {
		t.Fatalf("istemde profil bölümü yok:\n%s", sys)
	}
	iNoFab := strings.Index(sys, "fabrikasyon")
	if iNoFab >= 0 && iNoFab > iProfile {
		t.Fatalf("veri uydurmama kuralı profilden SONRA gelmeli (kurallar=%d profil=%d)", iNoFab, iProfile)
	}
}
