package push

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

func TestSubscriptionIDDeterministicAndHashed(t *testing.T) {
	const endpoint = "https://fcm.googleapis.com/fcm/send/abc123"

	id := SubscriptionID(endpoint)
	if got := SubscriptionID(endpoint); got != id {
		t.Fatalf("SubscriptionID not deterministic: %q vs %q", id, got)
	}
	if len(id) != 64 {
		t.Fatalf("SubscriptionID length = %d, want 64 (hex SHA-256)", len(id))
	}
	if strings.Contains(id, endpoint) {
		t.Fatal("SubscriptionID leaks the endpoint")
	}
	if SubscriptionID(endpoint+"x") == id {
		t.Fatal("distinct endpoints collide")
	}
}

func TestNewSenderInertWithoutKeys(t *testing.T) {
	s := NewSender(nil, "", "", "mailto:a@b.c")
	if s.Enabled() {
		t.Fatal("sender with no keys should be disabled")
	}
	if s.PublicKey() != "" {
		t.Fatal("disabled sender should expose no public key")
	}
	// Notify must be a safe no-op even with nil queries — callers invoke it
	// unconditionally and rely on the disabled short-circuit.
	s.Notify(context.Background(), "u", "d", Notification{Type: KindMessage})
}

func TestNewSenderEnabledWithKeys(t *testing.T) {
	s := NewSender(nil, "pub", "priv", "mailto:a@b.c")
	if !s.Enabled() {
		t.Fatal("sender with both keys should be enabled")
	}
	if s.PublicKey() != "pub" {
		t.Fatalf("PublicKey = %q, want pub", s.PublicKey())
	}
}

func TestNilSenderIsSafe(t *testing.T) {
	var s *Sender
	if s.Enabled() {
		t.Fatal("nil sender should report disabled")
	}
	if s.PublicKey() != "" {
		t.Fatal("nil sender should expose no public key")
	}
	s.Notify(context.Background(), "u", "d", Notification{}) // must not panic
}

func TestRenderTransferIncoming(t *testing.T) {
	n := Notification{
		Type:   KindTransferIncoming,
		Params: map[string]string{"sender": "Mac", "filename": "a.pdf"},
		Tag:    "transfer:1",
	}

	en := render(n, "en-US")
	if en.Title != "Incoming file" || en.Body != "Mac is sending a.pdf" {
		t.Fatalf("en render = %+v", en)
	}
	if en.Tag != "transfer:1" || en.URL != "/" {
		t.Fatalf("tag/url not carried through: %+v", en)
	}
	if en.Type != KindTransferIncoming {
		t.Fatalf("type = %q", en.Type)
	}

	zh := render(n, "zh-CN")
	if zh.Title != "收到文件" || zh.Body != "Mac 发来 a.pdf" {
		t.Fatalf("zh-CN render = %+v", zh)
	}

	tw := render(n, "zh-TW")
	if tw.Title != "收到檔案" || tw.Body != "Mac 傳來 a.pdf" {
		t.Fatalf("zh-TW render = %+v", tw)
	}
}

func TestRenderMessageIsPassthrough(t *testing.T) {
	n := Notification{
		Type:   KindMessage,
		Params: map[string]string{"sender": "Mac", "text": "hi there"},
	}
	// Locale is irrelevant for a message: title is the sender, body the text.
	for _, locale := range []string{"en-US", "zh-CN", "zh-TW", "fr-FR"} {
		got := render(n, locale)
		if got.Title != "Mac" || got.Body != "hi there" {
			t.Fatalf("message render(%s) = %+v", locale, got)
		}
	}
}

func TestRenderUnknownLocaleFallsBackToDefault(t *testing.T) {
	n := Notification{
		Type:   KindTransferDone,
		Params: map[string]string{"filename": "a.pdf"},
	}
	got := render(n, "fr-FR")
	want := render(n, defaultLocale)
	if got.Title != want.Title || got.Body != want.Body {
		t.Fatalf("unknown locale did not fall back: got %+v want %+v", got, want)
	}
	if got.Title != "传输完成" || got.Body != "a.pdf" {
		t.Fatalf("transfer:done render = %+v", got)
	}
}
