package schemautil

import (
	"testing"

	"github.com/nexuscrm/shared/pkg/fieldprovenance"
	"github.com/nexuscrm/shared/pkg/models"
)

func TestCompoundHelpersUseCanonicalFieldProvenanceOnly(t *testing.T) {
	previous := fieldprovenance.Default()
	defer fieldprovenance.SetDefault(previous)

	fieldprovenance.SetDefault(fieldprovenance.BuildClassifier(
		nil,
		[]fieldprovenance.ObjectDeclaration{{
			APIName: "PersonLike",
			Fields: []fieldprovenance.FieldDeclaration{
				{APIName: "Display", IsCompound: true, ComposedFrom: []string{"Prefix", "Given", "Family"}},
				{APIName: "Prefix"},
				{APIName: "Given"},
				{APIName: "Family"},
			},
		}},
		nil,
		nil,
	))

	schema := &models.ObjectMetadata{
		APIName: "PersonLike",
		Fields: []models.FieldMetadata{
			{APIName: "Display"},
			{APIName: "Prefix"},
			{APIName: "Given"},
			{APIName: "Family", IsNameField: true},
		},
	}

	if got, want := CompoundMemberNames(schema, "Display"), []string{"Prefix", "Given", "Family"}; !equalStringSlices(got, want) {
		t.Fatalf("CompoundMemberNames = %#v, want %#v", got, want)
	}
	if !HasCompoundMemberChange(schema, "Display", map[string]interface{}{"given": "Ada"}) {
		t.Fatal("HasCompoundMemberChange = false, want true for case-insensitive canonical member")
	}
	value, ok := CompoundFieldValue(schema, "Display", map[string]interface{}{"Prefix": "Dr.", "Given": "Ada", "Family": "Lovelace"})
	if !ok || value != "Dr. Ada Lovelace" {
		t.Fatalf("CompoundFieldValue = (%q, %v), want (%q, true)", value, ok, "Dr. Ada Lovelace")
	}
}

func TestCompoundHelpersDoNotInferNameFromIsNameFieldFallback(t *testing.T) {
	previous := fieldprovenance.Default()
	defer fieldprovenance.SetDefault(previous)

	fieldprovenance.SetDefault(fieldprovenance.NewClassifier(nil, nil, nil, nil))

	schema := &models.ObjectMetadata{
		APIName: "PersonLike",
		Fields: []models.FieldMetadata{
			{APIName: "Name"},
			{APIName: "Given", IsNameField: true},
			{APIName: "Family", IsNameField: true},
		},
	}

	if got := CompoundMemberNames(schema, "Name"); len(got) != 0 {
		t.Fatalf("CompoundMemberNames inferred from IsNameField = %#v, want nil", got)
	}
	if value, ok := CompoundFieldValue(schema, "Name", map[string]interface{}{"Given": "Ada", "Family": "Lovelace"}); ok {
		t.Fatalf("CompoundFieldValue inferred %q from IsNameField, want no value", value)
	}
}

func equalStringSlices(a, b []string) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}
