/*
Package validation provides methods for validating parameter value using reflection.
*/
package validation

// Copyright 2017 Microsoft Corporation
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

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

// Constraint stores constraint name, target field name
// Rule and chain validations.
type Constraint struct {

	// Target field name for validation.
	Target string

	// Constraint name e.g. minLength, MaxLength, Pattern, etc.
	Name string

	// Rule for constraint e.g. greater than 10, less than 5 etc.
	Rule interface{}

	// Chain Validations for struct type
	Chain []Constraint
}

// Validation stores parameter-wise validation.
type Validation struct {
	TargetValue interface{}
	Constraints []Constraint
}

// Constraint list
const (
	Empty            = "Empty"
	Null             = "Null"
	ReadOnly         = "ReadOnly"
	Pattern          = "Pattern"
	MaxLength        = "MaxLength"
	MinLength        = "MinLength"
	MaxItems         = "MaxItems"
	MinItems         = "MinItems"
	MultipleOf       = "MultipleOf"
	UniqueItems      = "UniqueItems"
	InclusiveMaximum = "InclusiveMaximum"
	ExclusiveMaximum = "ExclusiveMaximum"
	ExclusiveMinimum = "ExclusiveMinimum"
	InclusiveMinimum = "InclusiveMinimum"
)

// Validate method validates constraints on parameter
// passed in validation array.
func Validate(m []Validation) error {
	for _, item := range m {
		v := reflect.ValueOf(item.TargetValue)
		for _, constraint := range item.Constraints {
			var err error
			switch v.Kind() {
			case reflect.Ptr:
				err = validatePtr(v, constraint)
			case reflect.String:
				err = validateString(v, constraint)
			case reflect.Struct:
				err = validateStruct(v, constraint)
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
				err = validateInt(v, constraint)
			case reflect.Float32, reflect.Float64:
				err = validateFloat(v, constraint)
			case reflect.Array, reflect.Slice, reflect.Map:
				err = validateArrayMap(v, constraint)
			default:
				err = createError(v, constraint, fmt.Sprintf("unknown type %v", v.Kind()))
			}

			if err != nil {
				return err
			}
		}
	}
	return nil
}

func validateStruct(x reflect.Value, v Constraint, name ...string) error {
	//Get field name from target name which is in format a.b.c
	s := strings.Split(v.Target, ".")
	f := x.FieldByName(s[len(s)-1])
	if isZero(f) {
		return createError(x, v, fmt.Sprintf("field %q doesn't exist", v.Target))
	}

	return Validate([]Validation{
		{
			TargetValue: getInterfaceValue(f),
			Constraints: []Constraint{v},
		},
	})
}

func validatePtr(x reflect.Value, v Constraint) error {
	if v.Name == ReadOnly {
		if !x.IsNil() {
			return createError(x.Elem(), v, "readonly parameter; must send as nil or empty in request")
		}
		return nil
	}
	if x.IsNil() {
		return checkNil(x, v)
	}
	if v.Chain != nil {
		return Validate([]Validation{
			{
				TargetValue: getInterfaceValue(x.Elem()),
				Constraints: v.Chain,
			},
		})
	}
	return nil
}

func validateInt(x reflect.Value, v Constraint) error {
	i := x.Int()
	r, ok := toInt64(v.Rule)
	if !ok {
		return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule))
	}
	switch v.Name {
	case MultipleOf:
		if i%r != 0 {
			return createError(x, v, fmt.Sprintf("value must be a multiple of %v", r))
		}
	case ExclusiveMinimum:
		if i <= r {
			return createError(x, v, fmt.Sprintf("value must be greater than %v", r))
		}
	case ExclusiveMaximum:
		if i >= r {
			return createError(x, v, fmt.Sprintf("value must be less than %v", r))
		}
	case InclusiveMinimum:
		if i < r {
			return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r))
		}
	case InclusiveMaximum:
		if i > r {
			return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r))
		}
	default:
		return createError(x, v, fmt.Sprintf("constraint %v is not applicable for type integer", v.Name))
	}
	return nil
}

func validateFloat(x reflect.Value, v Constraint) error {
	f := x.Float()
	r, ok := v.Rule.(float64)
	if !ok {
		return createError(x, v, fmt.Sprintf("rule must be float value for %v constraint; got: %v", v.Name, v.Rule))
	}
	switch v.Name {
	case ExclusiveMinimum:
		if f <= r {
			return createError(x, v, fmt.Sprintf("value must be greater than %v", r))
		}
	case ExclusiveMaximum:
		if f >= r {
			return createError(x, v, fmt.Sprintf("value must be less than %v", r))
		}
	case InclusiveMinimum:
		if f < r {
			return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r))
		}
	case InclusiveMaximum:
		if f > r {
			return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r))
		}
	default:
		return createError(x, v, fmt.Sprintf("constraint %s is not applicable for type float", v.Name))
	}
	return nil
}

func validateString(x reflect.Value, v Constraint) error {
	s := x.String()
	switch v.Name {
	case Empty:
		if len(s) == 0 {
			return checkEmpty(x, v)
		}
	case Pattern:
		reg, err := regexp.Compile(v.Rule.(string))
		if err != nil {
			return createError(x, v, err.Error())
		}
		if !reg.MatchString(s) {
			return createError(x, v, fmt.Sprintf("value doesn't match pattern %v", v.Rule))
		}
	case MaxLength:
		if _, ok := v.Rule.(int); !ok {
			return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule))
		}
		if len(s) > v.Rule.(int) {
			return createError(x, v, fmt.Sprintf("value length must be less than or equal to %v", v.Rule))
		}
	case MinLength:
		if _, ok := v.Rule.(int); !ok {
			return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule))
		}
		if len(s) < v.Rule.(int) {
			return createError(x, v, fmt.Sprintf("value length must be greater than or equal to %v", v.Rule))
		}
	case ReadOnly:
		if len(s) > 0 {
			return createError(reflect.ValueOf(s), v, "readonly parameter; must send as nil or empty in request")
		}
	default:
		return createError(x, v, fmt.Sprintf("constraint %s is not applicable to string type", v.Name))
	}

	if v.Chain != nil {
		return Validate([]Validation{
			{
				TargetValue: getInterfaceValue(x),
				Constraints: v.Chain,
			},
		})
	}
	return nil
}

func validateArrayMap(x reflect.Value, v Constraint) error {
	switch v.Name {
	case Null:
		if x.IsNil() {
			return checkNil(x, v)
		}
	case Empty:
		if x.IsNil() || x.Len() == 0 {
			return checkEmpty(x, v)
		}
	case MaxItems:
		if _, ok := v.Rule.(int); !ok {
			return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.Name, v.Rule))
		}
		if x.Len() > v.Rule.(int) {
			return createError(x, v, fmt.Sprintf("maximum item limit is %v; got: %v", v.Rule, x.Len()))
		}
	case MinItems:
		if _, ok := v.Rule.(int); !ok {
			return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.Name, v.Rule))
		}
		if x.Len() < v.Rule.(int) {
			return createError(x, v, fmt.Sprintf("minimum item limit is %v; got: %v", v.Rule, x.Len()))
		}
	case UniqueItems:
		if x.Kind() == reflect.Array || x.Kind() == reflect.Slice {
			if !checkForUniqueInArray(x) {
				return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.Target, x))
			}
		} else if x.Kind() == reflect.Map {
			if !checkForUniqueInMap(x) {
				return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.Target, x))
			}
		} else {
			return createError(x, v, fmt.Sprintf("type must be array, slice or map for constraint %v; got: %v", v.Name, x.Kind()))
		}
	case ReadOnly:
		if x.Len() != 0 {
			return createError(x, v, "readonly parameter; must send as nil or empty in request")
		}
	case Pattern:
		reg, err := regexp.Compile(v.Rule.(string))
		if err != nil {
			return createError(x, v, err.Error())
		}
		keys := x.MapKeys()
		for _, k := range keys {
			if !reg.MatchString(k.String()) {
				return createError(k, v, fmt.Sprintf("map key doesn't match pattern %v", v.Rule))
			}
		}
	default:
		return createError(x, v, fmt.Sprintf("constraint %v is not applicable to array, slice and map type", v.Name))
	}

	if v.Chain != nil {
		return Validate([]Validation{
			{
				TargetValue: getInterfaceValue(x),
				Constraints: v.Chain,
			},
		})
	}
	return nil
}

func checkNil(x reflect.Value, v Constraint) error {
	if _, ok := v.Rule.(bool); !ok {
		return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.Name, v.Rule))
	}
	if v.Rule.(bool) {
		return createError(x, v, "value can not be null; required parameter")
	}
	return nil
}

func checkEmpty(x reflect.Value, v Constraint) error {
	if _, ok := v.Rule.(bool); !ok {
		return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.Name, v.Rule))
	}

	if v.Rule.(bool) {
		return createError(x, v, "value can not be null or empty; required parameter")
	}
	return nil
}

func checkForUniqueInArray(x reflect.Value) bool {
	if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 {
		return false
	}
	arrOfInterface := make([]interface{}, x.Len())

	for i := 0; i < x.Len(); i++ {
		arrOfInterface[i] = x.Index(i).Interface()
	}

	m := make(map[interface{}]bool)
	for _, val := range arrOfInterface {
		if m[val] {
			return false
		}
		m[val] = true
	}
	return true
}

func checkForUniqueInMap(x reflect.Value) bool {
	if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 {
		return false
	}
	mapOfInterface := make(map[interface{}]interface{}, x.Len())

	keys := x.MapKeys()
	for _, k := range keys {
		mapOfInterface[k.Interface()] = x.MapIndex(k).Interface()
	}

	m := make(map[interface{}]bool)
	for _, val := range mapOfInterface {
		if m[val] {
			return false
		}
		m[val] = true
	}
	return true
}

func getInterfaceValue(x reflect.Value) interface{} {
	if x.Kind() == reflect.Invalid {
		return nil
	}
	return x.Interface()
}

func isZero(x interface{}) bool {
	return x == reflect.Zero(reflect.TypeOf(x)).Interface()
}

func createError(x reflect.Value, v Constraint, err string) error {
	return fmt.Errorf("autorest/validation: validation failed: parameter=%s constraint=%s value=%#v details: %s",
		v.Target, v.Name, getInterfaceValue(x), err)
}

func toInt64(v interface{}) (int64, bool) {
	if i64, ok := v.(int64); ok {
		return i64, true
	}
	// older generators emit max constants as int, so if int64 fails fall back to int
	if i32, ok := v.(int); ok {
		return int64(i32), true
	}
	return 0, false
}

// NewErrorWithValidationError appends package type and method name in
// validation error.
//
// Deprecated: Please use validation.NewError() instead.
func NewErrorWithValidationError(err error, packageType, method string) error {
	return NewError(packageType, method, err.Error())
}
