package bootstrapimpl

import (
	"testing"

	domainschema "github.com/nexuscrm/kernel/pkg/schema"
)

func TestSystemTablesGeneratePolymorphicDiscriminatorColumns(t *testing.T) {
	defs := GetSystemTableDefinitions()

	groupMember := findSystemTableForPolyTest(t, defs, "GroupMember")
	userOrGroupID := findSystemColumnForPolyTest(t, groupMember.Columns, "UserOrGroupId")
	if !userOrGroupID.IsPolymorphic {
		t.Fatal("GroupMember.UserOrGroupId must be polymorphic metadata")
	}
	if !sameStringSlice(userOrGroupID.ReferenceTo, []string{"User", "Group"}) {
		t.Fatalf("GroupMember.UserOrGroupId referenceTo = %v, want [User Group]", userOrGroupID.ReferenceTo)
	}
	if len(userOrGroupID.WritableReferenceTo) != 0 {
		t.Fatalf("GroupMember.UserOrGroupId writableReferenceTo = %v, want unrestricted public targets", userOrGroupID.WritableReferenceTo)
	}
	userOrGroupType := findSystemColumnForPolyTest(t, groupMember.Columns, "UserOrGroupId_type")
	if userOrGroupType.Type != "VARCHAR(255)" || !userOrGroupType.Nullable {
		t.Fatalf("GroupMember.UserOrGroupId_type = %#v, want nullable VARCHAR(255)", userOrGroupType)
	}

	workitem := findSystemTableForPolyTest(t, defs, "ProcessInstanceWorkitem")
	_ = findSystemColumnForPolyTest(t, workitem.Columns, "ActorId_type")
	_ = findSystemColumnForPolyTest(t, workitem.Columns, "OriginalActorId_type")
}

func sameStringSlice(got, want []string) bool {
	if len(got) != len(want) {
		return false
	}
	for i := range got {
		if got[i] != want[i] {
			return false
		}
	}
	return true
}

func findSystemTableForPolyTest(t *testing.T, defs []domainschema.TableDefinition, tableName string) domainschema.TableDefinition {
	t.Helper()
	for _, def := range defs {
		if def.TableName == tableName {
			return def
		}
	}
	t.Fatalf("table %s not found", tableName)
	return domainschema.TableDefinition{}
}

func findSystemColumnForPolyTest(t *testing.T, columns []domainschema.ColumnDefinition, columnName string) domainschema.ColumnDefinition {
	t.Helper()
	for _, col := range columns {
		if col.Name == columnName {
			return col
		}
	}
	t.Fatalf("column %s not found", columnName)
	return domainschema.ColumnDefinition{}
}
