// Package utils contains utility functions for the parser package.
package utils

import (
	"maps"
	"strings"
)

// SetPathValue sets value at a dot-separated path in obj, creating maps as needed.
// If the path is only dots (e.g., "." or ".."):
//   - when obj == nil    -> returns value directly (e.g., "flour")
//   - when obj is a map  -> if value is a map[string]any, merge into obj; otherwise obj is unchanged.
//   - otherwise          -> returns obj unchanged.
func SetPathValue(path string, value any, obj any) any {
	// check if value is empty string and if so continue
	if value == "" || value == nil {
		return obj
	}

	// Split and drop empty segments (so ".", "..", "" become no keys)
	raw := strings.Split(path, ".")
	keys := raw[:0]
	for _, k := range raw {
		if k != "" {
			keys = append(keys, k)
		}
	}

	// Root case: no keys after trimming dots
	if len(keys) == 0 {
		if obj == nil {
			return value
		}
		if m, ok := obj.(map[string]any); ok {
			if mv, ok := value.(map[string]any); ok {
				maps.Copy(m, mv)
			}
			return m
		}
		return obj
	}

	// Ensure root is a map
	var root map[string]any
	if obj == nil {
		root = map[string]any{}
	} else if m, ok := obj.(map[string]any); ok {
		root = m
	} else {
		// if obj is not a map, just overwrite it with a new map
		root = map[string]any{}
	}

	// Descend/construct maps
	curr := root
	for i, k := range keys {
		if i == len(keys)-1 {
			curr[k] = value
			break
		}
		if next, ok := curr[k].(map[string]any); ok {
			curr = next
			continue
		}
		n := map[string]any{}
		curr[k] = n
		curr = n
	}
	return root
}
