// Copyright 2018 The CUE Authors
//
// 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.

package cue

import "cuelang.org/go/cue/token"

// Op indicates the operation at the top of an expression tree of the expression
// use to evaluate a value.
type Op int

func (o Op) String() string {
	return opToString[o]
}

// Values of Op.
const (
	NoOp Op = iota

	AndOp
	OrOp

	SelectorOp
	IndexOp
	SliceOp
	CallOp

	BooleanAndOp
	BooleanOrOp

	EqualOp
	NotOp
	NotEqualOp
	LessThanOp
	LessThanEqualOp
	GreaterThanOp
	GreaterThanEqualOp

	RegexMatchOp
	NotRegexMatchOp

	AddOp
	SubtractOp
	MultiplyOp
	FloatQuotientOp
	FloatRemainOp
	IntQuotientOp
	IntRemainderOp
	IntDivideOp
	IntModuloOp

	InterpolationOp
)

var opToOp = map[op]Op{
	opUnify: AndOp,
	// TODO(eval): opUnifyUnchecked is not the same as opUnify and should have its own
	// category, if needed. More likely opUnifyUnchecked, should be
	// represented as a separate embedding method.
	opUnifyUnchecked: AndOp,
	opDisjunction:    OrOp,
	opLand:           BooleanAndOp,
	opLor:            BooleanOrOp,
	opEql:            EqualOp,
	opNot:            NotOp,
	opNeq:            NotEqualOp,
	opLss:            LessThanOp,
	opLeq:            LessThanEqualOp,
	opGtr:            GreaterThanOp,
	opGeq:            GreaterThanEqualOp,
	opMat:            RegexMatchOp,
	opNMat:           NotRegexMatchOp,
	opAdd:            AddOp,
	opSub:            SubtractOp,
	opMul:            MultiplyOp,
	opQuo:            FloatQuotientOp,
	opRem:            FloatRemainOp,
	opIQuo:           IntQuotientOp,
	opIRem:           IntRemainderOp,
	opIDiv:           IntDivideOp,
	opIMod:           IntModuloOp,
}

var opToString = map[Op]string{
	AndOp:              "&",
	OrOp:               "|",
	BooleanAndOp:       "&&",
	BooleanOrOp:        "||",
	EqualOp:            "==",
	NotOp:              "!",
	NotEqualOp:         "!=",
	LessThanOp:         "<",
	LessThanEqualOp:    "<=",
	GreaterThanOp:      ">",
	GreaterThanEqualOp: ">=",
	RegexMatchOp:       "=~",
	NotRegexMatchOp:    "!~",
	AddOp:              "+",
	SubtractOp:         "-",
	MultiplyOp:         "*",
	FloatQuotientOp:    "/",
	FloatRemainOp:      "%",
	IntQuotientOp:      "quo",
	IntRemainderOp:     "rem",
	IntDivideOp:        "div",
	IntModuloOp:        "mod",

	SelectorOp:      ".",
	IndexOp:         "[]",
	SliceOp:         "[:]",
	CallOp:          "()",
	InterpolationOp: `\()`,
}

func opIn(op op, anyOf ...op) bool {
	for _, o := range anyOf {
		if o == op {
			return true
		}
	}
	return false
}

// isCmp reports whether an op is a comparator.
func (op op) isCmp() bool {
	return opEql <= op && op <= opGeq
}

func (op op) unifyType() (unchecked, ok bool) {
	if op == opUnifyUnchecked {
		return true, true
	}
	return false, op == opUnify
}

type op uint16

const (
	opUnknown op = iota

	opUnify
	opUnifyUnchecked
	opDisjunction

	opLand
	opLor
	opNot

	opEql
	opNeq
	opMat
	opNMat

	opLss
	opGtr
	opLeq
	opGeq

	opAdd
	opSub
	opMul
	opQuo
	opRem

	opIDiv
	opIMod
	opIQuo
	opIRem
)

var opStrings = []string{
	opUnknown: "??",

	opUnify: "&",
	// opUnifyUnchecked is internal only. Syntactically this is
	// represented as embedding.
	opUnifyUnchecked: "&!",
	opDisjunction:    "|",

	opLand: "&&",
	opLor:  "||",
	opNot:  "!",

	opEql:  "==",
	opNeq:  "!=",
	opMat:  "=~",
	opNMat: "!~",

	opLss: "<",
	opGtr: ">",
	opLeq: "<=",
	opGeq: ">=",

	opAdd: "+",
	opSub: "-",
	opMul: "*",
	opQuo: "/",

	opIDiv: "div",
	opIMod: "mod",
	opIQuo: "quo",
	opIRem: "rem",
}

func (op op) String() string { return opStrings[op] }

var tokenMap = map[token.Token]op{
	token.OR:  opDisjunction, // |
	token.AND: opUnify,       // &

	token.ADD: opAdd, // +
	token.SUB: opSub, // -
	token.MUL: opMul, // *
	token.QUO: opQuo, // /

	token.IDIV: opIDiv, // div
	token.IMOD: opIMod, // mod
	token.IQUO: opIQuo, // quo
	token.IREM: opIRem, // rem

	token.LAND: opLand, // &&
	token.LOR:  opLor,  // ||

	token.EQL: opEql, // ==
	token.LSS: opLss, // <
	token.GTR: opGtr, // >
	token.NOT: opNot, // !

	token.NEQ:  opNeq,  // !=
	token.LEQ:  opLeq,  // <=
	token.GEQ:  opGeq,  // >=
	token.MAT:  opMat,  // =~
	token.NMAT: opNMat, // !~
}

var opMap = map[op]token.Token{}

func init() {
	for t, o := range tokenMap {
		opMap[o] = t
	}
}
