package goneo

import (
	"reflect"
	"regexp"
	"strings"
)

const GoneoTagName = "goneo"

var supportedIdentifierFormat = regexp.MustCompile("^[a-zA-Z]+[_]*[a-zA-Z]+$")

const (
	unique    = "unique"
	omitEmpty = "omitempty"
)

var supportedAttributes = []string{omitEmpty, unique}

type reprTag struct {
	FieldName  string
	Identifier string
	Attributes map[string]bool
	Enabled    bool
}

func getTagsRepresentation(obj interface{}) (out map[string]reprTag) {
	if obj == nil {
		return nil
	}

	out = make(map[string]reprTag)
	t := asRefType(reflect.TypeOf(obj))
	for f := 0; f < t.NumField(); f++ {
		fld := t.Field(f)
		tag := strings.TrimSpace(fld.Tag.Get(GoneoTagName))

		// Mark ignored
		tagInstance := reprTag{
			Identifier: fld.Name,
			FieldName:  fld.Name,
			Attributes: make(map[string]bool),
		}
		if !strings.HasPrefix(tag, "-") {
			tagInstance.Enabled = true
		}

		// Process tag values when appropriate
		if tagInstance.Enabled {
			for _, attr := range supportedAttributes {
				oldTag := tag
				tag = strings.ReplaceAll(tag, attr, "")
				if tag != oldTag {
					tagInstance.Attributes[attr] = true
				}
			}
			rawIdentifier := strings.TrimSpace(strings.Split(tag, ",")[0])
			if supportedIdentifierFormat.MatchString(rawIdentifier) {
				tagInstance.Identifier = rawIdentifier
			}
		}

		out[fld.Name] = tagInstance
		out[tagInstance.Identifier] = tagInstance
	}
	return out
}