package mapstructure

import (
	"errors"
	"fmt"
	"reflect"
	"strings"
)

// MapToStruct takes a map and uses reflection to convert it into the
// given Go native structure. val must be a pointer to a struct.
func MapToStruct(m map[string]interface{}, rawVal interface{}) error {
	val := reflect.ValueOf(rawVal)
	if val.Kind() != reflect.Ptr {
		return errors.New("val must be a pointer")
	}

	val = val.Elem()
	if !val.CanAddr() {
		return errors.New("val must be addressable (a pointer)")
	}

	if val.Kind() != reflect.Struct {
		return errors.New("val must be an addressable struct")
	}

	valType := val.Type()

	for i := 0; i < valType.NumField(); i++ {
		fieldType := valType.Field(i)
		fieldName := fieldType.Name

		rawMapVal, ok := m[fieldName]
		if !ok {
			// Do a slower search by iterating over each key and
			// doing case-insensitive search.
			for mK, mV := range m {
				if strings.EqualFold(mK, fieldName) {
					rawMapVal = mV
					break
				}
			}

			if rawMapVal == nil {
				// There was no matching key in the map for the value in
				// the struct. Just ignore.
				continue
			}
		}

		field := val.Field(i)
		if !field.IsValid() {
			// This should never happen
			panic("field is not valid")
		}

		mapVal := reflect.ValueOf(rawMapVal)
		if !mapVal.IsValid() {
			// This should never happen because we got the value out
			// of the map.
			panic("map value is not valid")
		}

		mapValType := mapVal.Type()
		if !mapValType.AssignableTo(field.Type()) {
			// If the value in the map can't be assigned to the field
			// in the struct, then this is a problem...
			return fmt.Errorf(
				"field '%s' expected type '%s', got '%s'",
				fieldName, field.Type(), mapValType)
		}

		field.Set(mapVal)
	}

	return nil
}
