package discovery

import "testing"

func TestIsNoReplyEmail(t *testing.T) {
	cases := []struct {
		email string
		want  bool
	}{
		{"noreply@uber.com", true},
		{"no-reply@zoom.us", true},
		{"user@users.noreply.github.com", true},
		{"alice@corp.com", false},
		{"john.doe@company.com", false},
	}
	for _, tc := range cases {
		if got := isNoReplyEmail(tc.email); got != tc.want {
			t.Fatalf("isNoReplyEmail(%q) = %v, want %v", tc.email, got, tc.want)
		}
	}
}

func TestClassifyAddressNoReply(t *testing.T) {
	isML, _, _, reason := classifyAddress(&addressAgg{Email: "noreply@github.com"})
	if !isML {
		t.Fatal("expected noreply address to be classified as non-suggestable")
	}
	if !contains(reason, "no-reply") {
		t.Fatalf("expected no-reply in reason, got %q", reason)
	}
}

func TestIsMailingListDomain(t *testing.T) {
	if !isMailingListDomain("sendgrid.net") {
		t.Fatal("expected sendgrid.net to be mailing list")
	}
	if !isMailingListDomain("mail.example.sendgrid.net") {
		t.Fatal("expected subdomain of sendgrid")
	}
	if isMailingListDomain("gmail.com") {
		t.Fatal("gmail.com should not be mailing list")
	}
}

func TestClassifyAddressMailingListRatio(t *testing.T) {
	isML, _, _, _ := classifyAddress(&addressAgg{
		Email:        "news@company.com",
		MessageCount: 10,
		ListUnsub:    6,
	})
	if !isML {
		t.Fatal("expected majority list-unsubscribe signals to flag mailing list")
	}
}

func TestClassifyAddressSpamHeavyRatio(t *testing.T) {
	_, _, isSpam, _ := classifyAddress(&addressAgg{
		Email:        "spammer@evil.com",
		MessageCount: 4,
		SpamCount:    2,
	})
	if !isSpam {
		t.Fatal("expected 50% spam ratio with min 3 messages")
	}
}

func TestCompanyNamesMatch(t *testing.T) {
	if !companyNamesMatch("Acme Inc", "acme inc") {
		t.Fatal("expected case-insensitive company match")
	}
	if companyNamesMatch("Acme", "Globex") {
		t.Fatal("expected different companies not to match")
	}
}

func TestIsDisposableDomain(t *testing.T) {
	if !isDisposableDomain("yopmail.com") {
		t.Fatal("expected yopmail to be disposable")
	}
	if isDisposableDomain("company.com") {
		t.Fatal("company.com should not be disposable")
	}
}

func TestExtractSignature(t *testing.T) {
	body := "Hello there\n\n--\nJohn Doe\nCEO · Acme Inc\n+33 1 23 45 67 89"
	text, conf := extractSignature(body, "", "john@acme.com", "John Doe")
	if text == "" || conf < 0.5 {
		t.Fatalf("expected signature, got %q conf=%v", text, conf)
	}
	if !contains(text, "John Doe") {
		t.Fatalf("expected name in signature: %q", text)
	}
}

func TestDetectForwardedAddresses(t *testing.T) {
	body := "---------- Forwarded message ---------\nFrom: Alice <alice@example.com>\nSubject: Hi"
	addrs := detectForwardedAddresses(body, "")
	if len(addrs) != 1 || addrs[0] != "alice@example.com" {
		t.Fatalf("unexpected forwarded addrs: %v", addrs)
	}
}

func contains(s, sub string) bool {
	return len(s) >= len(sub) && (s == sub || len(sub) == 0 || indexOf(s, sub) >= 0)
}

func indexOf(s, sub string) int {
	for i := 0; i+len(sub) <= len(s); i++ {
		if s[i:i+len(sub)] == sub {
			return i
		}
	}
	return -1
}
