package testproto

import (
	"strings"
	"testing"

	"google.golang.org/protobuf/reflect/protoreflect"
)

func AssertHasJSONNameSetRecursive(t *testing.T, desc protoreflect.MessageDescriptor) {
	VisitFieldsRecursive(desc, func(field protoreflect.FieldDescriptor) {
		if !strings.HasPrefix(string(field.FullName()), "gitlab.agent.") {
			return
		}
		name := field.JSONName()
		if strings.ToLower(name) != name {
			t.Errorf("%s: set json_name option to a snake_case name", field.FullName())
		}
	})
}

func VisitFieldsRecursive(desc protoreflect.MessageDescriptor, v func(field protoreflect.FieldDescriptor)) {
	visitFieldsRecursive(map[protoreflect.FullName]struct{}{}, desc, v)
}

func visitFieldsRecursive(visited map[protoreflect.FullName]struct{}, desc protoreflect.MessageDescriptor, v func(field protoreflect.FieldDescriptor)) {
	fields := desc.Fields()
	for i := range fields.Len() {
		field := fields.Get(i)
		fullName := field.FullName()
		if _, ok := visited[fullName]; ok {
			continue
		}
		v(field)
		visited[fullName] = struct{}{}
		switch field.Kind() { //nolint:exhaustive
		case protoreflect.MessageKind, protoreflect.GroupKind:
			visitFieldsRecursive(visited, field.Message(), v)
		}
	}
}
