// Copyright 2016 Google Inc. All rights reserved.
//
// 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 parser

import (
	"fmt"
	"strings"
	"text/scanner"
)

type Node interface {
	// Pos returns the position of the first token in the Node
	Pos() scanner.Position
	// End returns the position of the character after the last token in the Node
	End() scanner.Position
}

// Definition is an Assignment or a Module at the top level of a Blueprints file
type Definition interface {
	Node
	String() string
	definitionTag()
}

// An Assignment is a variable assignment at the top level of a Blueprints file, scoped to the
// file and subdirs.
type Assignment struct {
	Name       string
	NamePos    scanner.Position
	Value      Expression
	OrigValue  Expression
	EqualsPos  scanner.Position
	Assigner   string
	Referenced bool
}

func (a *Assignment) String() string {
	return fmt.Sprintf("%s@%s %s %s (%s) %t", a.Name, a.EqualsPos, a.Assigner, a.Value, a.OrigValue, a.Referenced)
}

func (a *Assignment) Pos() scanner.Position { return a.NamePos }
func (a *Assignment) End() scanner.Position { return a.Value.End() }

func (a *Assignment) definitionTag() {}

// A Module is a module definition at the top level of a Blueprints file
type Module struct {
	Type    string
	TypePos scanner.Position
	Map
}

func (m *Module) Copy() *Module {
	ret := *m
	ret.Properties = make([]*Property, len(m.Properties))
	for i := range m.Properties {
		ret.Properties[i] = m.Properties[i].Copy()
	}
	return &ret
}

func (m *Module) String() string {
	propertyStrings := make([]string, len(m.Properties))
	for i, property := range m.Properties {
		propertyStrings[i] = property.String()
	}
	return fmt.Sprintf("%s@%s-%s{%s}", m.Type,
		m.LBracePos, m.RBracePos,
		strings.Join(propertyStrings, ", "))
}

func (m *Module) definitionTag() {}

func (m *Module) Pos() scanner.Position { return m.TypePos }
func (m *Module) End() scanner.Position { return m.Map.End() }

// A Property is a name: value pair within a Map, which may be a top level Module.
type Property struct {
	Name     string
	NamePos  scanner.Position
	ColonPos scanner.Position
	Value    Expression
}

func (p *Property) Copy() *Property {
	ret := *p
	ret.Value = p.Value.Copy()
	return &ret
}

func (p *Property) String() string {
	return fmt.Sprintf("%s@%s: %s", p.Name, p.ColonPos, p.Value)
}

func (p *Property) Pos() scanner.Position { return p.NamePos }
func (p *Property) End() scanner.Position { return p.Value.End() }

// A MapItem is a key: value pair within a Map, corresponding to map type, rather than a struct.
type MapItem struct {
	ColonPos scanner.Position
	Key      *String
	Value    Expression
}

func (m *MapItem) Copy() *MapItem {
	ret := MapItem{
		ColonPos: m.ColonPos,
		Key:      m.Key.Copy().(*String),
		Value:    m.Value.Copy(),
	}
	return &ret
}

func (m *MapItem) String() string {
	return fmt.Sprintf("%s@%s: %s", m.Key, m.ColonPos, m.Value)
}

func (m *MapItem) Pos() scanner.Position { return m.Key.Pos() }
func (m *MapItem) End() scanner.Position { return m.Value.End() }

// An Expression is a Value in a Property or Assignment.  It can be a literal (String or Bool), a
// Map, a List, an Operator that combines two expressions of the same type, or a Variable that
// references and Assignment.
type Expression interface {
	Node
	// Copy returns a copy of the Expression that will not affect the original if mutated
	Copy() Expression
	String() string
	// Type returns the underlying Type enum of the Expression if it were to be evalutated
	Type() Type
	// Eval returns an expression that is fully evaluated to a simple type (List, Map, String, or
	// Bool).  It will return the same object for every call to Eval().
	Eval() Expression
}

// ExpressionsAreSame tells whether the two values are the same Expression.
// This includes the symbolic representation of each Expression but not their positions in the original source tree.
// This does not apply any simplification to the expressions before comparing them
// (for example, "!!a" wouldn't be deemed equal to "a")
func ExpressionsAreSame(a Expression, b Expression) (equal bool, err error) {
	return hackyExpressionsAreSame(a, b)
}

// TODO(jeffrygaston) once positions are removed from Expression structs,
// remove this function and have callers use reflect.DeepEqual(a, b)
func hackyExpressionsAreSame(a Expression, b Expression) (equal bool, err error) {
	if a.Type() != b.Type() {
		return false, nil
	}
	left, err := hackyFingerprint(a)
	if err != nil {
		return false, nil
	}
	right, err := hackyFingerprint(b)
	if err != nil {
		return false, nil
	}
	areEqual := string(left) == string(right)
	return areEqual, nil
}

func hackyFingerprint(expression Expression) (fingerprint []byte, err error) {
	assignment := &Assignment{"a", noPos, expression, expression, noPos, "=", false}
	module := &File{}
	module.Defs = append(module.Defs, assignment)
	p := newPrinter(module)
	return p.Print()
}

type Type int

const (
	BoolType Type = iota + 1
	StringType
	Int64Type
	ListType
	MapType
	NotEvaluatedType
)

func (t Type) String() string {
	switch t {
	case BoolType:
		return "bool"
	case StringType:
		return "string"
	case Int64Type:
		return "int64"
	case ListType:
		return "list"
	case MapType:
		return "map"
	case NotEvaluatedType:
		return "notevaluated"
	default:
		panic(fmt.Errorf("Unknown type %d", t))
	}
}

type Operator struct {
	Args        [2]Expression
	Operator    rune
	OperatorPos scanner.Position
	Value       Expression
}

func (x *Operator) Copy() Expression {
	ret := *x
	ret.Args[0] = x.Args[0].Copy()
	ret.Args[1] = x.Args[1].Copy()
	return &ret
}

func (x *Operator) Eval() Expression {
	return x.Value.Eval()
}

func (x *Operator) Type() Type {
	return x.Args[0].Type()
}

func (x *Operator) Pos() scanner.Position { return x.Args[0].Pos() }
func (x *Operator) End() scanner.Position { return x.Args[1].End() }

func (x *Operator) String() string {
	return fmt.Sprintf("(%s %c %s = %s)@%s", x.Args[0].String(), x.Operator, x.Args[1].String(),
		x.Value, x.OperatorPos)
}

type Variable struct {
	Name    string
	NamePos scanner.Position
	Value   Expression
}

func (x *Variable) Pos() scanner.Position { return x.NamePos }
func (x *Variable) End() scanner.Position { return endPos(x.NamePos, len(x.Name)) }

func (x *Variable) Copy() Expression {
	ret := *x
	return &ret
}

func (x *Variable) Eval() Expression {
	return x.Value.Eval()
}

func (x *Variable) String() string {
	return x.Name + " = " + x.Value.String()
}

func (x *Variable) Type() Type { return x.Value.Type() }

type Map struct {
	LBracePos  scanner.Position
	RBracePos  scanner.Position
	Properties []*Property
	MapItems   []*MapItem
}

func (x *Map) Pos() scanner.Position { return x.LBracePos }
func (x *Map) End() scanner.Position { return endPos(x.RBracePos, 1) }

func (x *Map) Copy() Expression {
	ret := *x
	ret.Properties = make([]*Property, len(x.Properties))
	for i := range x.Properties {
		ret.Properties[i] = x.Properties[i].Copy()
	}
	ret.MapItems = make([]*MapItem, len(x.MapItems))
	for i := range x.MapItems {
		ret.MapItems[i] = x.MapItems[i].Copy()
	}
	return &ret
}

func (x *Map) Eval() Expression {
	if len(x.Properties) > 0 && len(x.MapItems) > 0 {
		panic("Cannot support both Properties and MapItems")
	}
	return x
}

func (x *Map) String() string {
	var s string
	if len(x.MapItems) > 0 {
		mapStrings := make([]string, len(x.MapItems))
		for i, mapItem := range x.MapItems {
			mapStrings[i] = mapItem.String()
		}
		s = strings.Join(mapStrings, ", ")
	} else {
		propertyStrings := make([]string, len(x.Properties))
		for i, property := range x.Properties {
			propertyStrings[i] = property.String()
		}
		s = strings.Join(propertyStrings, ", ")
	}
	return fmt.Sprintf("@%s-%s{%s}", x.LBracePos, x.RBracePos, s)
}

func (x *Map) Type() Type { return MapType }

// GetProperty looks for a property with the given name.
// It resembles the bracket operator of a built-in Golang map.
func (x *Map) GetProperty(name string) (Property *Property, found bool) {
	prop, found, _ := x.getPropertyImpl(name)
	return prop, found // we don't currently expose the index to callers
}

func (x *Map) getPropertyImpl(name string) (Property *Property, found bool, index int) {
	for i, prop := range x.Properties {
		if prop.Name == name {
			return prop, true, i
		}
	}
	return nil, false, -1
}

// RemoveProperty removes the property with the given name, if it exists.
func (x *Map) RemoveProperty(propertyName string) (removed bool) {
	_, found, index := x.getPropertyImpl(propertyName)
	if found {
		x.Properties = append(x.Properties[:index], x.Properties[index+1:]...)
	}
	return found
}

type List struct {
	LBracePos scanner.Position
	RBracePos scanner.Position
	Values    []Expression
}

func (x *List) Pos() scanner.Position { return x.LBracePos }
func (x *List) End() scanner.Position { return endPos(x.RBracePos, 1) }

func (x *List) Copy() Expression {
	ret := *x
	ret.Values = make([]Expression, len(x.Values))
	for i := range ret.Values {
		ret.Values[i] = x.Values[i].Copy()
	}
	return &ret
}

func (x *List) Eval() Expression {
	return x
}

func (x *List) String() string {
	valueStrings := make([]string, len(x.Values))
	for i, value := range x.Values {
		valueStrings[i] = value.String()
	}
	return fmt.Sprintf("@%s-%s[%s]", x.LBracePos, x.RBracePos,
		strings.Join(valueStrings, ", "))
}

func (x *List) Type() Type { return ListType }

type String struct {
	LiteralPos scanner.Position
	Value      string
}

func (x *String) Pos() scanner.Position { return x.LiteralPos }
func (x *String) End() scanner.Position { return endPos(x.LiteralPos, len(x.Value)+2) }

func (x *String) Copy() Expression {
	ret := *x
	return &ret
}

func (x *String) Eval() Expression {
	return x
}

func (x *String) String() string {
	return fmt.Sprintf("%q@%s", x.Value, x.LiteralPos)
}

func (x *String) Type() Type {
	return StringType
}

type Int64 struct {
	LiteralPos scanner.Position
	Value      int64
	Token      string
}

func (x *Int64) Pos() scanner.Position { return x.LiteralPos }
func (x *Int64) End() scanner.Position { return endPos(x.LiteralPos, len(x.Token)) }

func (x *Int64) Copy() Expression {
	ret := *x
	return &ret
}

func (x *Int64) Eval() Expression {
	return x
}

func (x *Int64) String() string {
	return fmt.Sprintf("%q@%s", x.Value, x.LiteralPos)
}

func (x *Int64) Type() Type {
	return Int64Type
}

type Bool struct {
	LiteralPos scanner.Position
	Value      bool
	Token      string
}

func (x *Bool) Pos() scanner.Position { return x.LiteralPos }
func (x *Bool) End() scanner.Position { return endPos(x.LiteralPos, len(x.Token)) }

func (x *Bool) Copy() Expression {
	ret := *x
	return &ret
}

func (x *Bool) Eval() Expression {
	return x
}

func (x *Bool) String() string {
	return fmt.Sprintf("%t@%s", x.Value, x.LiteralPos)
}

func (x *Bool) Type() Type {
	return BoolType
}

type CommentGroup struct {
	Comments []*Comment
}

func (x *CommentGroup) Pos() scanner.Position { return x.Comments[0].Pos() }
func (x *CommentGroup) End() scanner.Position { return x.Comments[len(x.Comments)-1].End() }

type Comment struct {
	Comment []string
	Slash   scanner.Position
}

func (c Comment) Pos() scanner.Position {
	return c.Slash
}

func (c Comment) End() scanner.Position {
	pos := c.Slash
	for _, comment := range c.Comment {
		pos.Offset += len(comment) + 1
		pos.Column = len(comment) + 1
	}
	pos.Line += len(c.Comment) - 1
	return pos
}

func (c Comment) String() string {
	l := 0
	for _, comment := range c.Comment {
		l += len(comment) + 1
	}
	buf := make([]byte, 0, l)
	for _, comment := range c.Comment {
		buf = append(buf, comment...)
		buf = append(buf, '\n')
	}

	return string(buf) + "@" + c.Slash.String()
}

// Return the text of the comment with // or /* and */ stripped
func (c Comment) Text() string {
	l := 0
	for _, comment := range c.Comment {
		l += len(comment) + 1
	}
	buf := make([]byte, 0, l)

	blockComment := false
	if strings.HasPrefix(c.Comment[0], "/*") {
		blockComment = true
	}

	for i, comment := range c.Comment {
		if blockComment {
			if i == 0 {
				comment = strings.TrimPrefix(comment, "/*")
			}
			if i == len(c.Comment)-1 {
				comment = strings.TrimSuffix(comment, "*/")
			}
		} else {
			comment = strings.TrimPrefix(comment, "//")
		}
		buf = append(buf, comment...)
		buf = append(buf, '\n')
	}

	return string(buf)
}

type NotEvaluated struct {
	Position scanner.Position
}

func (n NotEvaluated) Copy() Expression {
	return NotEvaluated{Position: n.Position}
}

func (n NotEvaluated) String() string {
	return "Not Evaluated"
}

func (n NotEvaluated) Type() Type {
	return NotEvaluatedType
}

func (n NotEvaluated) Eval() Expression {
	return NotEvaluated{Position: n.Position}
}

func (n NotEvaluated) Pos() scanner.Position { return n.Position }
func (n NotEvaluated) End() scanner.Position { return n.Position }

func endPos(pos scanner.Position, n int) scanner.Position {
	pos.Offset += n
	pos.Column += n
	return pos
}
