/*
 * Copyright 2026 Oleg Borodin <onborodin@gmail.com>
 *
 * This work is published and licensed under a Creative Commons
 * Attribution-NonCommercial-NoDerivatives 4.0 International License.
 *
 * Distribution of this work is permitted, but commercial use and
 * modifications are strictly prohibited.
 */
package router

import (
	"reflect"
	"strconv"
)

// The code reflect string-string map to taged structure
// Limited, used only base types
// Don't ask me how it works. I'm only writer ;)

func bindObj(obj interface{}, kvmap map[string]string, sTag string) error {
	var err error
	vElem := reflect.ValueOf(obj).Elem()
	sElem := reflect.TypeOf(obj).Elem()
	for i := 0; i < vElem.NumField(); i++ {
		vField := vElem.Field(i)
		tag := sElem.Field(i).Tag.Get(sTag)
		if tag != "" {
			sVal, exists := kvmap[tag]
			if exists {
				switch vField.Kind() {
				case reflect.String:
					vField.SetString(sVal)
				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
					iVal, err := strconv.ParseInt(sVal, 10, 64)
					if err != nil {
						return err
					}
					vField.SetInt(iVal)
				case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
					iVal, err := strconv.ParseUint(sVal, 10, 64)
					if err != nil {
						return err
					}
					vField.SetUint(iVal)
				case reflect.Bool:
					bVal, err := strconv.ParseBool(sVal)
					if err != nil {
						return err
					}
					vField.SetBool(bVal)
				case reflect.Float32, reflect.Float64:
					fVal, err := strconv.ParseFloat(sVal, 64)
					if err != nil {
						return err
					}
					vField.SetFloat(fVal)
				}
			}
		}
	}
	return err
}
