package runner

import (
	"strings"
	"testing"
)

func TestBuildCacheAffinityKeyUsesExplicitKeyFirst(t *testing.T) {
	body := map[string]any{
		"cacheAffinityKey": "session-a",
		"sessionId":        "session-b",
		"messages":         []any{map[string]any{"role": "user", "content": "hello"}},
	}

	got := buildCacheAffinityKey("chat.completions", "text_generate", body)
	if !strings.HasPrefix(got, "explicit:") {
		t.Fatalf("expected explicit cache affinity key, got %q", got)
	}
}

func TestBuildCacheAffinityKeyUsesSessionContinuity(t *testing.T) {
	got := buildCacheAffinityKey("chat.completions", "text_generate", map[string]any{
		"session_id": "conversation-1",
	})

	if !strings.HasPrefix(got, "session_id:") {
		t.Fatalf("expected session cache affinity key, got %q", got)
	}
}

func TestBuildCacheAffinityKeyFallsBackToPromptHash(t *testing.T) {
	body := map[string]any{
		"messages": []any{
			map[string]any{"role": "system", "content": "stable"},
			map[string]any{"role": "user", "content": "hello"},
		},
		"tools": []any{map[string]any{"type": "function", "function": map[string]any{"name": "lookup"}}},
	}

	first := buildCacheAffinityKey("chat.completions", "text_generate", body)
	second := buildCacheAffinityKey("chat.completions", "text_generate", body)
	if first == "" || first != second || !strings.HasPrefix(first, "prompt_lcp:") {
		t.Fatalf("expected stable prompt LCP cache affinity key, first=%q second=%q", first, second)
	}
}

func TestBuildCacheAffinityKeysUsesMessagePrefixLCPKeys(t *testing.T) {
	first := buildCacheAffinityKeys("chat.completions", "text_generate", map[string]any{
		"messageHashes": []any{"system-hash", "user-hash"},
		"tools":         []any{map[string]any{"type": "function", "function": map[string]any{"name": "lookup"}}},
	})
	next := buildCacheAffinityKeys("chat.completions", "text_generate", map[string]any{
		"messageHashes": []any{"system-hash", "user-hash", "assistant-hash", "tool-hash"},
		"tools":         []any{map[string]any{"type": "function", "function": map[string]any{"name": "lookup"}}},
	})

	if !strings.HasPrefix(first.Primary, "prompt_lcp:") {
		t.Fatalf("expected LCP prompt key, got %+v", first)
	}
	if len(first.Record) != 2 || len(next.Lookup) != 4 {
		t.Fatalf("expected per-message prefix keys, first=%+v next=%+v", first, next)
	}
	found := false
	for _, key := range next.Lookup {
		if key == first.Primary {
			found = true
			break
		}
	}
	if !found {
		t.Fatalf("next lookup keys should include first request prefix key, first=%+v next=%+v", first, next)
	}
}
