package main

import (
	"strings"
	"testing"
)

func TestSourcesFooter(t *testing.T) {
	redirect := "https://vertexaisearch.cloud.google.com/grounding-api-redirect/abc"
	src := []WebSource{
		{Title: "rbc.ru", URL: redirect + "1"},
		{Title: "www.tass.ru", URL: redirect + "2"},
		{Title: "rbc.ru", URL: redirect + "3"}, // duplicate domain → collapsed
		{Title: "lenta.ru", URL: redirect + "4"},
		{Title: "vedomosti.ru", URL: redirect + "5"}, // beyond maxSourcesShown → dropped
	}

	// Russian answer → Russian label, deduped, capped, www stripped, clickable.
	got := sourcesFooter("Да, удалили 3 июня.", src)
	want := "\n\nИсточники: [rbc.ru](" + redirect + "1), [tass.ru](" + redirect + "2), [lenta.ru](" + redirect + "4)"
	if got != want {
		t.Fatalf("sourcesFooter ru =\n %q\nwant\n %q", got, want)
	}

	// English answer → English label.
	if got := sourcesFooter("Yes, removed on June 3.", src[:1]); !strings.HasPrefix(got, "\n\nSources: [rbc.ru](") {
		t.Fatalf("sourcesFooter en = %q", got)
	}

	// No usable sources → empty (no trailing label on a grok_direct/empty answer).
	if got := sourcesFooter("привет", nil); got != "" {
		t.Fatalf("empty sources should yield no footer, got %q", got)
	}
	// A source missing a title or URL is skipped.
	if got := sourcesFooter("hi", []WebSource{{Title: "", URL: redirect}, {Title: "x.com", URL: ""}}); got != "" {
		t.Fatalf("incomplete sources should yield no footer, got %q", got)
	}
}

func TestDisplayDomain(t *testing.T) {
	cases := map[string]string{
		"xn----7sbbtpiaccnexupfs6l4c.xn--p1ai": "крымская-косметика.рф", // real hyphenated .рф from a grounding result
		"xn--80aswg.xn--p1ai":                  "сайт.рф",               // .рф IDN → readable Cyrillic, not "xn--…"
		"www.xn--80aswg.xn--p1ai":              "сайт.рф",               // www stripped first, then decoded
		"wikipedia.org":                        "wikipedia.org",         // ASCII passes through unchanged
		"www.youtube.com":                      "youtube.com",
		"  rbc.ru  ":                           "rbc.ru",
		"xn--80ak6aa92e.com":                   "аррӏе.com", // homograph decodes too — fine, the label is not the click target
		"xn--invalid-punycode-":                "invalid-punycode",
		"":                                     "",
	}
	for in, want := range cases {
		if got := displayDomain(in); got != want {
			t.Errorf("displayDomain(%q) = %q, want %q", in, got, want)
		}
	}
}

func TestHostOf(t *testing.T) {
	cases := map[string]string{
		"https://www.reuters.com/world/article-123": "reuters.com",
		"https://rbc.ru/politics/03/06/2026":        "rbc.ru",
		"https://xn--80aswg.xn--p1ai/p":             "сайт.рф", // IDN host decoded to Unicode for display
		"not a url":                                 "",
		"":                                          "",
	}
	for in, want := range cases {
		if got := hostOf(in); got != want {
			t.Errorf("hostOf(%q) = %q, want %q", in, got, want)
		}
	}
}
