package discovery

import "testing"

func TestDiscoveryFieldMatchScoreExactAndPrefix(t *testing.T) {
	if got := discoveryFieldMatchScore("Alice Martin", "alice martin"); got != 1 {
		t.Fatalf("exact match: got %v want 1", got)
	}
	prefix := discoveryFieldMatchScore("alice@example.com", "alice")
	if prefix < 0.95 {
		t.Fatalf("email prefix too low: %v", prefix)
	}
}

func TestRankProfileGroupsByQueryOrder(t *testing.T) {
	groups := []ProfileGroup{
		{
			DisplayName: "Jonathan Smith",
			Profile:     Profile{DisplayName: "Jonathan Smith", PrimaryEmail: "jonathan@corp.com"},
			Profiles:    []Profile{{DisplayName: "Jonathan Smith", PrimaryEmail: "jonathan@corp.com"}},
		},
		{
			DisplayName: "Jon Smith",
			Profile:     Profile{DisplayName: "Jon Smith", PrimaryEmail: "jon@corp.com"},
			Profiles:    []Profile{{DisplayName: "Jon Smith", PrimaryEmail: "jon@corp.com"}},
		},
		{
			DisplayName: "Bob Builder",
			Profile:     Profile{DisplayName: "Bob Builder", PrimaryEmail: "bob@corp.com"},
			Profiles:    []Profile{{DisplayName: "Bob Builder", PrimaryEmail: "bob@corp.com"}},
		},
	}
	ranked := rankProfileGroupsByQuery(groups, "jon")
	if len(ranked) != 2 {
		t.Fatalf("expected 2 matches, got %d", len(ranked))
	}
	if ranked[0].DisplayName != "Jon Smith" {
		t.Fatalf("expected Jon Smith first, got %q", ranked[0].DisplayName)
	}
}

func TestRankProfileGroupsByQueryRequiresAllTokens(t *testing.T) {
	groups := []ProfileGroup{
		{
			DisplayName: "John Doe",
			Profile:     Profile{DisplayName: "John Doe", PrimaryEmail: "john@corp.com"},
			Profiles:    []Profile{{DisplayName: "John Doe", PrimaryEmail: "john@corp.com"}},
		},
		{
			DisplayName: "John Smith",
			Profile:     Profile{DisplayName: "John Smith", PrimaryEmail: "john@other.com"},
			Profiles:    []Profile{{DisplayName: "John Smith", PrimaryEmail: "john@other.com"}},
		},
	}
	ranked := rankProfileGroupsByQuery(groups, "john doe")
	if len(ranked) != 1 {
		t.Fatalf("expected 1 match, got %d", len(ranked))
	}
	if ranked[0].DisplayName != "John Doe" {
		t.Fatalf("expected John Doe, got %q", ranked[0].DisplayName)
	}
}

func TestRankProfileGroupsByQueryNoFuzzy(t *testing.T) {
	groups := []ProfileGroup{
		{
			DisplayName: "Jonathan",
			Profile:     Profile{DisplayName: "Jonathan", PrimaryEmail: "jonathan@corp.com"},
			Profiles:    []Profile{{DisplayName: "Jonathan", PrimaryEmail: "jonathan@corp.com"}},
		},
	}
	ranked := rankProfileGroupsByQuery(groups, "jhn")
	if len(ranked) != 0 {
		t.Fatalf("expected no fuzzy match, got %d", len(ranked))
	}
}

func TestRankProfileGroupsByQuerySecondaryEmail(t *testing.T) {
	groups := []ProfileGroup{
		{
			DisplayName: "Contact",
			Profile: Profile{
				DisplayName:  "Contact",
				PrimaryEmail: "main@corp.com",
				AllEmails:    []EmailEntry{{Email: "alias@corp.com", DisplayName: "Alias"}},
			},
			Profiles: []Profile{{
				DisplayName:  "Contact",
				PrimaryEmail: "main@corp.com",
				AllEmails:    []EmailEntry{{Email: "alias@corp.com", DisplayName: "Alias"}},
			}},
		},
	}
	ranked := rankProfileGroupsByQuery(groups, "alias")
	if len(ranked) != 1 {
		t.Fatalf("expected match on secondary email, got %d", len(ranked))
	}
}
