// 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,
	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
	}
}
