// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package query

import (
	"errors"
	"fmt"
	"math/big"
	"reflect"
	"strconv"

	"v.io/syncbase/v23/syncbase/nosql/internal/query/query_checker"
	"v.io/syncbase/v23/syncbase/nosql/internal/query/query_parser"
)

func Eval(k string, v interface{}, e *query_parser.Expression) bool {
	if query_checker.IsLogicalOperator(e.Operator) {
		return evalLogicalOperators(k, v, e)
	} else {
		return evalComparisonOperators(k, v, e)
	}
}

func evalLogicalOperators(k string, v interface{}, e *query_parser.Expression) bool {
	switch e.Operator.Type {
	case query_parser.And:
		return Eval(k, v, e.Operand1.Expr) && Eval(k, v, e.Operand2.Expr)
	default: // query_parser.Or
		return Eval(k, v, e.Operand1.Expr) || Eval(k, v, e.Operand2.Expr)
	}
}

func evalComparisonOperators(k string, v interface{}, e *query_parser.Expression) bool {
	// Key and type expressions are evaluated differently from value expression.
	// Key expressions always have a string literal on the rhs and are currently
	// limited to = and <>.
	// Type expressions are limited to = and must have a stiring literal rhs.  Also,
	// they are evaluated via reflection on the value.
	if query_checker.IsKey(e.Operand1) {
		return evalKeyExpression(e, k)
	} else if query_checker.IsType(e.Operand1) {
		return evalTypeExpression(e, v)
	} else {
		return evalValueExpression(k, v, e)
	}
}

func evalValueExpression(k string, v interface{}, e *query_parser.Expression) bool {
	// Any fields that are value fields that need to be resolved.
	lhsValue := resolveOperand(v, e.Operand1)
	if lhsValue == nil {
		return false
	}
	rhsValue := resolveOperand(v, e.Operand2)
	if rhsValue == nil {
		return false
	}
	// coerce operands so they are comparable
	var err error
	lhsValue, rhsValue, err = coerceValues(lhsValue, rhsValue)
	if err != nil {
		return false // If operands can't be coerced to compare, expr evals to false.
	}
	// Do the compare
	switch lhsValue.Type {
	case query_parser.TypBigInt:
		return compareBigInts(lhsValue, rhsValue, e.Operator)
	case query_parser.TypBigRat:
		return compareBigRats(lhsValue, rhsValue, e.Operator)
	case query_parser.TypBool:
		return compareBools(lhsValue, rhsValue, e.Operator)
	case query_parser.TypFloat:
		return compareFloats(lhsValue, rhsValue, e.Operator)
	case query_parser.TypInt:
		return compareInts(lhsValue, rhsValue, e.Operator)
	case query_parser.TypLiteral:
		return compareStrings(lhsValue, rhsValue, e.Operator)
	case query_parser.TypUint:
		return compareUints(lhsValue, rhsValue, e.Operator)
	case query_parser.TypObject:
		return compareObjects(lhsValue, rhsValue, e.Operator)
	}
	return false
}

func coerceValues(lhsValue, rhsValue *query_parser.Operand) (*query_parser.Operand, *query_parser.Operand, error) {
	var err error
	// If either operand is a string, convert the other to a string.
	if lhsValue.Type == query_parser.TypLiteral || rhsValue.Type == query_parser.TypLiteral {
		if lhsValue, err = convertValueToString(lhsValue); err != nil {
			return nil, nil, err
		}
		if rhsValue, err = convertValueToString(rhsValue); err != nil {
			return nil, nil, err
		}
	}
	// If either operand is a big rat, convert both to a big rat.
	// Also, if one operand is a float and the other is a big int,
	// convert both to big rats.
	if lhsValue.Type == query_parser.TypBigRat || rhsValue.Type == query_parser.TypBigRat || (lhsValue.Type == query_parser.TypBigInt && rhsValue.Type == query_parser.TypFloat) || (lhsValue.Type == query_parser.TypFloat && rhsValue.Type == query_parser.TypBigInt) {
		if lhsValue, err = convertValueToBigRat(lhsValue); err != nil {
			return nil, nil, err
		}
		if rhsValue, err = convertValueToBigRat(rhsValue); err != nil {
			return nil, nil, err
		}
	}
	// If either operand is a float, convert the other to a float.
	if lhsValue.Type == query_parser.TypFloat || rhsValue.Type == query_parser.TypFloat {
		if lhsValue, err = convertValueToFloat(lhsValue); err != nil {
			return nil, nil, err
		}
		if rhsValue, err = convertValueToFloat(rhsValue); err != nil {
			return nil, nil, err
		}
	}
	// If either operand is a big int, convert both to a big int.
	// Also, if one operand is a uint64 and the other is an int64, convert both to big ints.
	if lhsValue.Type == query_parser.TypBigInt || rhsValue.Type == query_parser.TypBigInt || (lhsValue.Type == query_parser.TypUint && rhsValue.Type == query_parser.TypInt) || (lhsValue.Type == query_parser.TypInt && rhsValue.Type == query_parser.TypUint) {
		if lhsValue, err = convertValueToBigInt(lhsValue); err != nil {
			return nil, nil, err
		}
		if rhsValue, err = convertValueToBigInt(rhsValue); err != nil {
			return nil, nil, err
		}
	}
	// If either operand is an int64, convert the other to int64.
	if lhsValue.Type == query_parser.TypInt || rhsValue.Type == query_parser.TypInt {
		if lhsValue, err = convertValueToInt(lhsValue); err != nil {
			return nil, nil, err
		}
		if rhsValue, err = convertValueToInt(rhsValue); err != nil {
			return nil, nil, err
		}
	}
	// If either operand is an uint64, convert the other to uint64.
	if lhsValue.Type == query_parser.TypUint || rhsValue.Type == query_parser.TypUint {
		if lhsValue, err = convertValueToUint(lhsValue); err != nil {
			return nil, nil, err
		}
		if rhsValue, err = convertValueToUint(rhsValue); err != nil {
			return nil, nil, err
		}
	}
	// Must be the same at this point.
	if lhsValue.Type != rhsValue.Type {
		return nil, nil, errors.New(fmt.Sprintf("Logic error: expeced like types, got: %v, %v", lhsValue, rhsValue))
	}

	return lhsValue, rhsValue, nil
}

func convertValueToString(o *query_parser.Operand) (*query_parser.Operand, error) {
	var c query_parser.Operand
	c.Type = query_parser.TypLiteral
	switch o.Type {
	case query_parser.TypBigInt:
		c.Literal = o.BigInt.String()
	case query_parser.TypBigRat:
		c.Literal = o.BigRat.String()
	case query_parser.TypBool:
		c.Literal = strconv.FormatBool(o.Bool)
	case query_parser.TypFloat:
		c.Literal = strconv.FormatFloat(o.Float, 'f', -1, 64)
	case query_parser.TypInt:
		c.Literal = strconv.FormatInt(o.Int, 10)
	case query_parser.TypLiteral:
		c.Literal = o.Literal
		c.Regex = o.Regex         // non-nil for rhs of like expressions
		c.CompRegex = o.CompRegex // non-nil for rhs of like expressions
	case query_parser.TypUint:
		c.Literal = strconv.FormatUint(o.Uint, 10)
	default: // query_parser.TypObject
		return nil, errors.New("Cannot convert object to string for comparison.")
	}
	return &c, nil
}

func convertValueToBigRat(o *query_parser.Operand) (*query_parser.Operand, error) {
	// operand cannot be literal.
	var c query_parser.Operand
	c.Type = query_parser.TypBigRat
	switch o.Type {
	case query_parser.TypBigInt:
		var b big.Rat
		c.BigRat = b.SetInt(o.BigInt)
	case query_parser.TypBigRat:
		c.BigRat = o.BigRat
	case query_parser.TypBool:
		return nil, errors.New("Cannot convert bool to big.Rat for comparison.")
	case query_parser.TypFloat:
		var b big.Rat
		c.BigRat = b.SetFloat64(o.Float)
	case query_parser.TypInt:
		c.BigRat = big.NewRat(o.Int, 1)
	case query_parser.TypUint:
		var bi big.Int
		bi.SetUint64(o.Uint)
		var br big.Rat
		c.BigRat = br.SetInt(&bi)
	default: // query_parser.TypObject
		return nil, errors.New("Cannot convert object to big.Rat for comparison.")
	}
	return &c, nil
}

func convertValueToFloat(o *query_parser.Operand) (*query_parser.Operand, error) {
	// Operand cannot be literal, big.Rat or big.Int
	var c query_parser.Operand
	c.Type = query_parser.TypFloat
	switch o.Type {
	case query_parser.TypBool:
		return nil, errors.New("Cannot convert bool to float64 for comparison.")
	case query_parser.TypFloat:
		c.Float = o.Float
	case query_parser.TypInt:
		c.Float = float64(o.Int)
	case query_parser.TypUint:
		c.Float = float64(o.Uint)
	default: // query_parser.TypObject
		return nil, errors.New("Cannot convert object to float64 for comparison.")
	}
	return &c, nil
}

func convertValueToBigInt(o *query_parser.Operand) (*query_parser.Operand, error) {
	// Operand cannot be literal, big.Rat or float.
	var c query_parser.Operand
	c.Type = query_parser.TypBigInt
	switch o.Type {
	case query_parser.TypBigInt:
		c.BigInt = o.BigInt
	case query_parser.TypBool:
		return nil, errors.New("Cannot convert bool to big.Int for comparison.")
	case query_parser.TypInt:
		c.BigInt = big.NewInt(o.Int)
	case query_parser.TypUint:
		var b big.Int
		b.SetUint64(o.Uint)
		c.BigInt = &b
	default: // case query_parser.TypObject
		return nil, errors.New("Cannot convert object to big.Int for comparison.")
	}
	return &c, nil
}

func convertValueToInt(o *query_parser.Operand) (*query_parser.Operand, error) {
	// Operand cannot be literal, big.Rat or float or uint64.
	var c query_parser.Operand
	c.Type = query_parser.TypInt
	switch o.Type {
	case query_parser.TypBool:
		return nil, errors.New("Cannot convert bool to int64 for comparison.")
	case query_parser.TypInt:
		c.Int = o.Int
	default: //case query_parser.TypObject
		return nil, errors.New("Cannot convert object to int64 for comparison.")
	}
	return &c, nil
}

func convertValueToUint(o *query_parser.Operand) (*query_parser.Operand, error) {
	// Operand cannot be literal, big.Rat or float or int64.
	var c query_parser.Operand
	c.Type = query_parser.TypUint
	switch o.Type {
	case query_parser.TypBool:
		return nil, errors.New("Cannot convert bool to int64 for comparison.")
	case query_parser.TypUint:
		c.Uint = o.Uint
	default: //case query_parser.TypObject
		return nil, errors.New("Cannot convert object to int64 for comparison.")
	}
	return &c, nil
}

func compareBools(lhsValue, rhsValue *query_parser.Operand, oper *query_parser.BinaryOperator) bool {
	switch oper.Type {
	case query_parser.Equal:
		return lhsValue.Bool == rhsValue.Bool
	default: // query_parser.NotEqual
		return lhsValue.Bool != rhsValue.Bool
	}
}

func compareBigInts(lhsValue, rhsValue *query_parser.Operand, oper *query_parser.BinaryOperator) bool {
	switch oper.Type {
	case query_parser.Equal:
		return lhsValue.BigInt.Cmp(rhsValue.BigInt) == 0
	case query_parser.NotEqual:
		return lhsValue.BigInt.Cmp(rhsValue.BigInt) != 0
	case query_parser.LessThan:
		return lhsValue.BigInt.Cmp(rhsValue.BigInt) < 0
	case query_parser.LessThanOrEqual:
		return lhsValue.BigInt.Cmp(rhsValue.BigInt) <= 0
	case query_parser.GreaterThan:
		return lhsValue.BigInt.Cmp(rhsValue.BigInt) > 0
	default: // case query_parser.GreaterThanOrEqual
		return lhsValue.BigInt.Cmp(rhsValue.BigInt) >= 0
	}
}

func compareBigRats(lhsValue, rhsValue *query_parser.Operand, oper *query_parser.BinaryOperator) bool {
	switch oper.Type {
	case query_parser.Equal:
		return lhsValue.BigRat.Cmp(rhsValue.BigRat) == 0
	case query_parser.NotEqual:
		return lhsValue.BigRat.Cmp(rhsValue.BigRat) != 0
	case query_parser.LessThan:
		return lhsValue.BigRat.Cmp(rhsValue.BigRat) < 0
	case query_parser.LessThanOrEqual:
		return lhsValue.BigRat.Cmp(rhsValue.BigRat) <= 0
	case query_parser.GreaterThan:
		return lhsValue.BigRat.Cmp(rhsValue.BigRat) > 0
	default: // case query_parser.GreaterThanOrEqual
		return lhsValue.BigRat.Cmp(rhsValue.BigRat) >= 0
	}
}

func compareFloats(lhsValue, rhsValue *query_parser.Operand, oper *query_parser.BinaryOperator) bool {
	switch oper.Type {
	case query_parser.Equal:
		return lhsValue.Float == rhsValue.Float
	case query_parser.NotEqual:
		return lhsValue.Float != rhsValue.Float
	case query_parser.LessThan:
		return lhsValue.Float < rhsValue.Float
	case query_parser.LessThanOrEqual:
		return lhsValue.Float <= rhsValue.Float
	case query_parser.GreaterThan:
		return lhsValue.Float > rhsValue.Float
	default: // case query_parser.GreaterThanOrEqual
		return lhsValue.Float >= rhsValue.Float
	}
}

func compareInts(lhsValue, rhsValue *query_parser.Operand, oper *query_parser.BinaryOperator) bool {
	switch oper.Type {
	case query_parser.Equal:
		return lhsValue.Int == rhsValue.Int
	case query_parser.NotEqual:
		return lhsValue.Int != rhsValue.Int
	case query_parser.LessThan:
		return lhsValue.Int < rhsValue.Int
	case query_parser.LessThanOrEqual:
		return lhsValue.Int <= rhsValue.Int
	case query_parser.GreaterThan:
		return lhsValue.Int > rhsValue.Int
	default: // case query_parser.GreaterThanOrEqual
		return lhsValue.Int >= rhsValue.Int
	}
}

func compareUints(lhsValue, rhsValue *query_parser.Operand, oper *query_parser.BinaryOperator) bool {
	switch oper.Type {
	case query_parser.Equal:
		return lhsValue.Uint == rhsValue.Uint
	case query_parser.NotEqual:
		return lhsValue.Uint != rhsValue.Uint
	case query_parser.LessThan:
		return lhsValue.Uint < rhsValue.Uint
	case query_parser.LessThanOrEqual:
		return lhsValue.Uint <= rhsValue.Uint
	case query_parser.GreaterThan:
		return lhsValue.Uint > rhsValue.Uint
	default: // case query_parser.GreaterThanOrEqual
		return lhsValue.Uint >= rhsValue.Uint
	}
}

func compareStrings(lhsValue, rhsValue *query_parser.Operand, oper *query_parser.BinaryOperator) bool {
	switch oper.Type {
	case query_parser.Equal:
		return lhsValue.Literal == rhsValue.Literal
	case query_parser.NotEqual:
		return lhsValue.Literal != rhsValue.Literal
	case query_parser.LessThan:
		return lhsValue.Literal < rhsValue.Literal
	case query_parser.LessThanOrEqual:
		return lhsValue.Literal <= rhsValue.Literal
	case query_parser.GreaterThan:
		return lhsValue.Literal > rhsValue.Literal
	case query_parser.GreaterThanOrEqual:
		return lhsValue.Literal >= rhsValue.Literal
	case query_parser.Like:
		return rhsValue.CompRegex.MatchString(lhsValue.Literal)
	default: // query_parser.NotLike:
		return !rhsValue.CompRegex.MatchString(lhsValue.Literal)
	}
}

func compareObjects(lhsValue, rhsValue *query_parser.Operand, oper *query_parser.BinaryOperator) bool {
	switch oper.Type {
	case query_parser.Equal:
		return reflect.DeepEqual(lhsValue.Object, rhsValue.Object)
	case query_parser.NotEqual:
		return !reflect.DeepEqual(lhsValue.Object, rhsValue.Object)
	default: // other operands are non-sensical
		return false
	}
}

func resolveOperand(v interface{}, o *query_parser.Operand) *query_parser.Operand {
	if o.Type != query_parser.TypField {
		return o
	}
	value := ResolveField(v, o.Column)

	// Convert value to an operand
	var newOp query_parser.Operand
	newOp.Off = o.Off

	switch value := value.(type) {
	case bool:
		newOp.Type = query_parser.TypBool
		newOp.Bool = value
	case int:
		newOp.Type = query_parser.TypInt
		newOp.Int = int64(value)
	case int8:
		newOp.Type = query_parser.TypInt
		newOp.Int = int64(value)
	case int16:
		newOp.Type = query_parser.TypInt
		newOp.Int = int64(value)
	case int32: // rune
		newOp.Type = query_parser.TypInt
		newOp.Int = int64(value)
	case int64:
		newOp.Type = query_parser.TypInt
		newOp.Int = value
	case uint:
		newOp.Type = query_parser.TypBigInt
		var b big.Int
		b.SetUint64(uint64(value))
		newOp.BigInt = &b
	case uint8: // byte
		newOp.Type = query_parser.TypInt
		newOp.Int = int64(value)
	case uint16:
		newOp.Type = query_parser.TypInt
		newOp.Int = int64(value)
	case uint32:
		newOp.Type = query_parser.TypInt
		newOp.Int = int64(value)
	case uint64:
		newOp.Type = query_parser.TypBigInt
		var b big.Int
		b.SetUint64(value)
		newOp.BigInt = &b
	case float32:
		newOp.Type = query_parser.TypFloat
		newOp.Float = float64(value)
	case float64:
		newOp.Type = query_parser.TypFloat
		newOp.Float = value
	case string:
		newOp.Type = query_parser.TypLiteral
		newOp.Literal = value
	case *big.Int:
		newOp.Type = query_parser.TypBigInt
		newOp.BigInt = value
	case *big.Rat:
		newOp.Type = query_parser.TypBigRat
		newOp.BigRat = value
	default: // OpObject for structs, arrays, maps, ...
		newOp.Type = query_parser.TypObject
		newOp.Object = value
	}
	return &newOp
}

func ResolveField(v interface{}, f *query_parser.Field) interface{} {
	var object interface{}
	object = v
	segments := f.Segments
	// The first segment will always be v itself, skip it.
	for i := 1; i < len(segments); i++ {
		// object must be a struct in order to look for the next segment.
		if reflect.ValueOf(object).Kind() != reflect.Struct {
			return nil // field does not exist
		}
		// Look up the segment in object.
		_, ok := reflect.ValueOf(object).Type().FieldByName(segments[i].Value)
		if !ok {
			return nil // field does not exist
		}
		if !reflect.ValueOf(object).FieldByName(segments[i].Value).CanInterface() {
			return nil
		}
		object = reflect.ValueOf(object).FieldByName(segments[i].Value).Interface()
	}
	return object
}

// Evaluate an expression where the first operand refers to the key.
func evalKeyExpression(e *query_parser.Expression, k string) bool {
	// Need to evaluate the key expression.
	// Currently, only = and like are allowed.
	// Operand2 must be a string literal.
	switch e.Operator.Type {
	case query_parser.Equal:
		return k == e.Operand2.Literal
	default: // query_parse.Like
		return e.Operand2.CompRegex.MatchString(k)
	}
}

func evalTypeExpression(e *query_parser.Expression, v interface{}) bool {
	if v == nil {
		// The type expression does not match.
		return false
	}
	// First try to match on the full type.
	if reflect.ValueOf(v).Type().PkgPath()+"."+reflect.ValueOf(v).Type().Name() == e.Operand2.Literal {
		return true
	}
	// Try to match on just the name.
	return reflect.ValueOf(v).Type().Name() == e.Operand2.Literal
}

// Evaluate the where clause, substituting false for all expressions involving the key and
// true for all other expressions.  If the answer is true, it is possible to satisfy the
// expression for any key.  As such, all keys must be fetched.
func CheckIfAllKeysMustBeFetched(e *query_parser.Expression) bool {
	switch e.Operator.Type {
	case query_parser.And:
		return CheckIfAllKeysMustBeFetched(e.Operand1.Expr) && CheckIfAllKeysMustBeFetched(e.Operand2.Expr)
	case query_parser.Or:
		return CheckIfAllKeysMustBeFetched(e.Operand1.Expr) || CheckIfAllKeysMustBeFetched(e.Operand2.Expr)
	default: // =, > >=, <, <=, Like, <>, NotLike
		if query_checker.IsKey(e.Operand1) {
			return false
		} else {
			return true
		}
	}
}

// Evaluate the where clause to determine if the row should be selected, but do so using only
// the key.  Possible returns are:
// true: the row should included in the results
// false: the row should NOT be included
// error: the value and/or type of the value are required to determine if row should be included.
// The above decision is accomplished by evaluating all expressions which reference the key and
// substituing false for all other expressions.  If the result is true, true is returned.
// If the result is false, but no other experssions (i.e., expressions which refer to the type
// of the value or the value itself) were encountered, false is returned; else, an error is
// returned indicating the value must be fetched in order to determine if the row should be included
// in the results.
func EvalWhereUsingOnlyKey(s *query_parser.SelectStatement, k string) (bool, error) {
	if s.Where == nil { // all rows will be in result
		return true, nil
	}
	return evalExprUsingOnlyKey(s.Where.Expr, k)
}

func evalExprUsingOnlyKey(e *query_parser.Expression, k string) (bool, error) {
	switch e.Operator.Type {
	case query_parser.And:
		op1Result, err1 := evalExprUsingOnlyKey(e.Operand1.Expr, k)
		op2Result, err2 := evalExprUsingOnlyKey(e.Operand2.Expr, k)
		if op1Result && op2Result {
			return true, nil
		} else if (op1Result == false && err1 == nil) || (op2Result == false && err2 == nil) {
			// One of the operands evaluated to false with no error.
			// As such, the value is not needed to reject the row.
			return false, nil
		} else {
			if err1 != nil {
				return false, err1
			} else {
				return false, err2
			}
		}
	case query_parser.Or:
		op1Result, err1 := evalExprUsingOnlyKey(e.Operand1.Expr, k)
		op2Result, err2 := evalExprUsingOnlyKey(e.Operand2.Expr, k)
		if op1Result || op2Result {
			return true, nil
		} else {
			if err1 != nil {
				return false, err1
			} else {
				return false, err2 // err2 may or may not be nil
			}
		}
	default: // =, > >=, <, <=, Like, <>, NotLike
		if !query_checker.IsKey(e.Operand1) {
			// Non-key expressions are evaluated as false.
			return false, errors.New("Value required for answer.") // err text not used
		} else {
			return evalKeyExpression(e, k), nil
		}
	}
}
