// 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_functions

import (
	"strings"

	"v.io/syncbase/v23/syncbase/nosql/internal/query/conversions"
	"v.io/syncbase/v23/syncbase/nosql/internal/query/query_parser"
	"v.io/syncbase/v23/syncbase/nosql/query_db"
	"v.io/syncbase/v23/syncbase/nosql/syncql"
	"v.io/v23/vdl"
)

type queryFunc func(query_db.Database, int64, []*query_parser.Operand) (*query_parser.Operand, error)
type checkArgsFunc func(query_db.Database, int64, []*query_parser.Operand) error

type function struct {
	argTypes      []query_parser.OperandType
	returnType    query_parser.OperandType
	funcAddr      queryFunc
	checkArgsAddr checkArgsFunc
}

var functions map[string]function
var lowercaseFunctions map[string]string // map of lowercase(funcName)->funcName

func init() {
	functions = make(map[string]function)

	functions["Date"] = function{[]query_parser.OperandType{query_parser.TypStr}, query_parser.TypTime, date, singleTimeArgCheck}
	functions["DateTime"] = function{[]query_parser.OperandType{query_parser.TypStr}, query_parser.TypTime, dateTime, singleTimeArgCheck}
	functions["Y"] = function{[]query_parser.OperandType{query_parser.TypStr, query_parser.TypStr}, query_parser.TypTime, y, timeAndStringArgsCheck}
	functions["YM"] = function{[]query_parser.OperandType{query_parser.TypStr, query_parser.TypStr}, query_parser.TypTime, ym, timeAndStringArgsCheck}
	functions["YMD"] = function{[]query_parser.OperandType{query_parser.TypStr, query_parser.TypStr}, query_parser.TypTime, ymd, timeAndStringArgsCheck}
	functions["YMDH"] = function{[]query_parser.OperandType{query_parser.TypStr, query_parser.TypStr}, query_parser.TypTime, ymdh, timeAndStringArgsCheck}
	functions["YMDHM"] = function{[]query_parser.OperandType{query_parser.TypStr, query_parser.TypStr}, query_parser.TypTime, ymdhm, timeAndStringArgsCheck}
	functions["YMDHMS"] = function{[]query_parser.OperandType{query_parser.TypStr, query_parser.TypStr}, query_parser.TypTime, ymdhms, timeAndStringArgsCheck}
	functions["Now"] = function{[]query_parser.OperandType{}, query_parser.TypTime, now, nil}

	functions["Lowercase"] = function{[]query_parser.OperandType{query_parser.TypStr}, query_parser.TypStr, lowerCase, singleStringArgCheck}
	functions["Split"] = function{[]query_parser.OperandType{query_parser.TypStr, query_parser.TypStr}, query_parser.TypObject, split, twoStringArgsCheck}
	functions["Type"] = function{[]query_parser.OperandType{query_parser.TypObject}, query_parser.TypStr, typeFunc, singleFieldArgCheck}
	functions["Uppercase"] = function{[]query_parser.OperandType{query_parser.TypStr}, query_parser.TypStr, upperCase, singleStringArgCheck}

	functions["Complex"] = function{[]query_parser.OperandType{query_parser.TypFloat, query_parser.TypFloat}, query_parser.TypComplex, complexFunc, twoFloatsArgsCheck}

	functions["Len"] = function{[]query_parser.OperandType{query_parser.TypObject}, query_parser.TypInt, lenFunc, nil}

	// Build lowercaseFuncName->funcName
	lowercaseFunctions = make(map[string]string)
	for f := range functions {
		lowercaseFunctions[strings.ToLower(f)] = f
	}
}

// Check that function exists and that the number of args passed matches the spec.
// Call query_functions.CheckFunction.  This will check for correct number of args
// and, to the extent possible, correct types.
// Furthermore, it may execute the function if the function takes no args or
// takes only literal args (or an arg that is a function that is also executed
// early).  CheckFunction will fill in arg types, return types and may fill in
// Computed and RetValue.
func CheckFunction(db query_db.Database, f *query_parser.Function) error {
	if entry, err := lookupFuncName(db, f); err != nil {
		return err
	} else {
		f.ArgTypes = entry.argTypes
		f.RetType = entry.returnType
		if len(f.ArgTypes) != len(f.Args) {
			return syncql.NewErrFunctionArgCount(db.GetContext(), f.Off, f.Name, int64(len(f.ArgTypes)), int64(len(f.Args)))
		}
		// Check if the function can be executed now.
		// If any arg is not a literal and not a function that has been already executed,
		// then okToExecuteNow will be set to false.
		okToExecuteNow := true
		for _, arg := range f.Args {
			switch arg.Type {
			case query_parser.TypBigInt, query_parser.TypBigRat, query_parser.TypBool, query_parser.TypComplex, query_parser.TypFloat, query_parser.TypInt, query_parser.TypStr, query_parser.TypTime, query_parser.TypUint:
				// do nothing
			case query_parser.TypFunction:
				if !arg.Function.Computed {
					okToExecuteNow = false
					break
				}
			default:
				okToExecuteNow = false
				break
			}
		}
		// If all of the functions args are literals or already computed functions,
		// execute this function now and save the result.
		if okToExecuteNow {
			op, err := ExecFunction(db, f, f.Args)
			if err != nil {
				return err
			}
			f.Computed = true
			f.RetValue = op
			return nil
		} else {
			// We can't execute now, but give the function a chance to complain
			// about the arguments that it can check now.
			return FuncCheck(db, f, f.Args)
		}
	}
}

func lookupFuncName(db query_db.Database, f *query_parser.Function) (*function, error) {
	if entry, ok := functions[f.Name]; !ok {
		// No such function, is the case wrong?
		if correctCase, ok := lowercaseFunctions[strings.ToLower(f.Name)]; !ok {
			return nil, syncql.NewErrFunctionNotFound(db.GetContext(), f.Off, f.Name)
		} else {
			// the case is wrong
			return nil, syncql.NewErrDidYouMeanFunction(db.GetContext(), f.Off, correctCase)
		}
	} else {
		return &entry, nil
	}
}

func FuncCheck(db query_db.Database, f *query_parser.Function, args []*query_parser.Operand) error {
	if entry, err := lookupFuncName(db, f); err != nil {
		return err
	} else {
		if entry.checkArgsAddr != nil {
			if err := entry.checkArgsAddr(db, f.Off, args); err != nil {
				return err
			}
		}
	}
	return nil
}

func ExecFunction(db query_db.Database, f *query_parser.Function, args []*query_parser.Operand) (*query_parser.Operand, error) {
	if entry, err := lookupFuncName(db, f); err != nil {
		return nil, err
	} else {
		retValue, err := entry.funcAddr(db, f.Off, args)
		if err != nil {
			return nil, err
		} else {
			return retValue, nil
		}
	}
}

func ConvertFunctionRetValueToVdlValue(o *query_parser.Operand) *vdl.Value {
	if o == nil {
		return vdl.ValueOf(nil)
	}
	switch o.Type {
	case query_parser.TypBool:
		return vdl.ValueOf(o.Bool)
	case query_parser.TypComplex:
		return vdl.ValueOf(o.Complex)
	case query_parser.TypFloat:
		return vdl.ValueOf(o.Float)
	case query_parser.TypInt:
		return vdl.ValueOf(o.Int)
	case query_parser.TypStr:
		return vdl.ValueOf(o.Str)
	case query_parser.TypTime:
		return vdl.ValueOf(o.Time)
	case query_parser.TypObject:
		return vdl.ValueOf(o.Object)
	case query_parser.TypUint:
		return vdl.ValueOf(o.Uint)
	default:
		// Other types can't be converted and *shouldn't* be returned
		// from a function.  This case will result in a nil for this
		// column in the row.
		return vdl.ValueOf(nil)
	}
}

func makeStrOp(off int64, s string) *query_parser.Operand {
	var o query_parser.Operand
	o.Off = off
	o.Type = query_parser.TypStr
	o.Str = s
	return &o
}

func makeComplexOp(off int64, c complex128) *query_parser.Operand {
	var o query_parser.Operand
	o.Off = off
	o.Type = query_parser.TypComplex
	o.Complex = c
	return &o
}

func makeIntOp(off int64, i int64) *query_parser.Operand {
	var o query_parser.Operand
	o.Off = off
	o.Type = query_parser.TypInt
	o.Int = i
	return &o
}

func singleStringArgCheck(db query_db.Database, off int64, args []*query_parser.Operand) error {
	return checkIfPossibleThatArgIsConvertableToString(db, args[0])
}

func twoStringArgsCheck(db query_db.Database, off int64, args []*query_parser.Operand) error {
	if err := checkIfPossibleThatArgIsConvertableToString(db, args[0]); err != nil {
		return err
	}
	return checkIfPossibleThatArgIsConvertableToString(db, args[1])
}

func singleFieldArgCheck(db query_db.Database, off int64, args []*query_parser.Operand) error {
	// single argument must be of type field
	// It must begin with a v segment.
	if args[0].Type != query_parser.TypField || len(args[0].Column.Segments) < 1 || args[0].Column.Segments[0].Value != "v" {
		return syncql.NewErrArgMustBeField(db.GetContext(), args[0].Off)
	}
	return nil
}

// If possible, check if arg is convertable to a string.  Fields and not yet computed
// functions cannot be checked and will just return nil.
func checkIfPossibleThatArgIsConvertableToString(db query_db.Database, arg *query_parser.Operand) error {
	// If arg is a literal or an already computed function,
	// make sure it can be converted to a string.
	switch arg.Type {
	case query_parser.TypBigInt, query_parser.TypBigRat, query_parser.TypBool, query_parser.TypComplex, query_parser.TypFloat, query_parser.TypInt, query_parser.TypStr, query_parser.TypTime, query_parser.TypUint:
		_, err := conversions.ConvertValueToString(arg)
		if err != nil {
			return syncql.NewErrStringConversionError(db.GetContext(), arg.Off, err)
		} else {
			return nil
		}
	case query_parser.TypFunction:
		if arg.Function.Computed {
			_, err := conversions.ConvertValueToString(arg.Function.RetValue)
			if err != nil {
				return syncql.NewErrStringConversionError(db.GetContext(), arg.Off, err)
			} else {
				return nil
			}
		}
	}
	return nil
}
