package helper

import "fmt"

// MapString is a map[string]interface{} which always unmarsahls yaml to map[string]interface{}
type MapString map[string]interface{}

// UnmarshalYAML handles all maps as map[string]interface{} for later JSON
// see https://github.com/elastic/beats/blob/6435194af9f42cbf778ca0a1a92276caf41a0da8/libbeat/common/mapstr.go
func (ms *MapString) UnmarshalYAML(unmarshal func(interface{}) error) error {
	var result map[interface{}]interface{}
	err := unmarshal(&result)
	if err != nil {
		return err
	}
	*ms = cleanUpInterfaceMap(result)
	return nil
}

func cleanUpInterfaceArray(in []interface{}) []interface{} {
	result := make([]interface{}, len(in))
	for i, v := range in {
		result[i] = cleanUpMapValue(v)
	}
	return result
}

func cleanUpInterfaceMap(in map[interface{}]interface{}) MapString {
	result := make(MapString)
	for k, v := range in {
		result[fmt.Sprintf("%v", k)] = cleanUpMapValue(v)
	}
	return result
}

func cleanUpMapValue(v interface{}) interface{} {
	switch v := v.(type) {
	case []interface{}:
		return cleanUpInterfaceArray(v)
	case map[interface{}]interface{}:
		return cleanUpInterfaceMap(v)
	case string, bool, int, int8, int16, int32, int64, float32, float64:
		return v
	default:
		return fmt.Sprintf("%v", v)
	}
}
