package models

import (
	"reflect"
	"strings"
	"testing"
)

func gormTag(t *testing.T, model any, field string) string {
	t.Helper()
	rt := reflect.TypeOf(model)
	sf, ok := rt.FieldByName(field)
	if !ok {
		t.Fatalf("field %s not found on %s", field, rt.Name())
	}
	return sf.Tag.Get("gorm")
}

func TestIndexedStringColumnsHaveBoundedSize(t *testing.T) {
	cases := []struct {
		name      string
		model     any
		field     string
		mustHave  []string
		mustAvoid []string
	}{
		{
			name:      "Engineer.Email unique index must include size",
			model:     Engineer{},
			field:     "Email",
			mustHave:  []string{"size:191", "uniqueIndex"},
			mustAvoid: []string{"type:text", "longtext"},
		},
		{
			name:      "ApiKey.KeyHash unique index must include size",
			model:     ApiKey{},
			field:     "KeyHash",
			mustHave:  []string{"size:191", "uniqueIndex"},
			mustAvoid: []string{"type:text", "longtext"},
		},
		{
			name:      "ApiKey.Email index must include size",
			model:     ApiKey{},
			field:     "Email",
			mustHave:  []string{"size:191", "index"},
			mustAvoid: []string{"type:text", "longtext"},
		},
		{
			name:      "SuperAdmin.Email unique index must include size",
			model:     SuperAdmin{},
			field:     "Email",
			mustHave:  []string{"size:191", "uniqueIndex"},
			mustAvoid: []string{"type:text", "longtext"},
		},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			tag := gormTag(t, tc.model, tc.field)
			for _, want := range tc.mustHave {
				if !strings.Contains(tag, want) {
					t.Fatalf("gorm tag missing %q, got: %q", want, tag)
				}
			}
			for _, bad := range tc.mustAvoid {
				if strings.Contains(tag, bad) {
					t.Fatalf("gorm tag should not include %q, got: %q", bad, tag)
				}
			}
		})
	}
}
