// 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 ast declares the types used to represent syntax trees for CUE
// packages.
package ast // import "cuelang.org/go/cue/ast"

import (
	"strconv"
	"strings"

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

// ----------------------------------------------------------------------------
// Interfaces
//
// There are two main classes of nodes: expressions, clauses, and declaration
// nodes. The node names usually match the corresponding CUE spec production
// names to which they correspond. The node fields correspond to the individual
// parts of the respective productions.
//
// All nodes contain position information marking the beginning of the
// corresponding source text segment; it is accessible via the Pos accessor
// method. Nodes may contain additional position info for language constructs
// where comments may be found between parts of the construct (typically any
// larger, parenthesized subpart). That position information is needed to
// properly position comments when printing the construct.

// A Node represents any node in the abstract syntax tree.
type Node interface {
	Pos() token.Pos // position of first character belonging to the node
	End() token.Pos // position of first character immediately after the node

	// TODO: SetPos(p token.RelPos)

	Comments() []*CommentGroup
	AddComment(*CommentGroup)
}

// An Expr is implemented by all expression nodes.
type Expr interface {
	Node
	exprNode()
}

func (*BadExpr) exprNode()       {}
func (*Ident) exprNode()         {}
func (*BasicLit) exprNode()      {}
func (*Interpolation) exprNode() {}
func (*StructLit) exprNode()     {}
func (*ListLit) exprNode()       {}
func (*Ellipsis) exprNode()      {}

// func (*Comprehension) exprNode() {}
func (*ListComprehension) exprNode() {}
func (*ParenExpr) exprNode()         {}
func (*SelectorExpr) exprNode()      {}
func (*IndexExpr) exprNode()         {}
func (*SliceExpr) exprNode()         {}
func (*CallExpr) exprNode()          {}
func (*UnaryExpr) exprNode()         {}
func (*BinaryExpr) exprNode()        {}
func (*BottomLit) exprNode()         {}

// A Decl node is implemented by all declarations.
type Decl interface {
	Node
	declNode()
}

func (*Field) declNode()         {}
func (*Comprehension) declNode() {}
func (*ImportDecl) declNode()    {}
func (*BadDecl) declNode()       {}
func (*EmbedDecl) declNode()     {}
func (*Alias) declNode()         {}
func (*Ellipsis) declNode()      {}

// Not technically declarations, but appearing at the same level.
func (*Package) declNode()      {}
func (*CommentGroup) declNode() {}

// A Label is any prduction that can be used as a LHS label.
type Label interface {
	Node
	labelName() (name string, isIdent bool)
}

func (n *Ident) labelName() (string, bool) {
	return n.Name, true
}

func (n *BasicLit) labelName() (string, bool) {
	switch n.Kind {
	case token.STRING:
		// Use strconv to only allow double-quoted, single-line strings.
		if str, err := strconv.Unquote(n.Value); err == nil {
			return str, true
		}
	case token.NULL, token.TRUE, token.FALSE:
		return n.Value, true

		// TODO: allow numbers to be fields?
	}
	return "", false
}

func (n *TemplateLabel) labelName() (string, bool) {
	return n.Ident.Name, false
}

func (n *Interpolation) labelName() (string, bool) {
	return "", false
}

// LabelName reports the name of a label, if known, and whether it is valid.
func LabelName(x Label) (name string, ok bool) {
	return x.labelName()
}

// Clause nodes are part of comprehensions.
type Clause interface {
	Node
	clauseNode()
}

func (x *ForClause) clauseNode() {}
func (x *IfClause) clauseNode()  {}
func (x *Alias) clauseNode()     {}

// Comments

type comments struct {
	groups *[]*CommentGroup
}

func (c *comments) Comments() []*CommentGroup {
	if c.groups == nil {
		return []*CommentGroup{}
	}
	return *c.groups
}

// // AddComment adds the given comments to the fields.
// // If line is true the comment is inserted at the preceding token.

func (c *comments) AddComment(cg *CommentGroup) {
	if cg == nil {
		return
	}
	if c.groups == nil {
		a := []*CommentGroup{cg}
		c.groups = &a
		return
	}
	*c.groups = append(*c.groups, cg)
}

// A Comment node represents a single //-style or /*-style comment.
type Comment struct {
	Slash token.Pos // position of "/" starting the comment
	Text  string    // comment text (excluding '\n' for //-style comments)
}

func (g *Comment) Comments() []*CommentGroup { return nil }
func (g *Comment) AddComment(*CommentGroup)  {}

func (c *Comment) Pos() token.Pos { return c.Slash }
func (c *Comment) End() token.Pos { return c.Slash.Add(len(c.Text)) }

// A CommentGroup represents a sequence of comments
// with no other tokens and no empty lines between.
type CommentGroup struct {
	// TODO: remove and use the token position of the first comment.
	Doc  bool
	Line bool // true if it is on the same line as the node's end pos.

	// Position indicates where a comment should be attached if a node has
	// multiple tokens. 0 means before the first token, 1 means before the
	// second, etc. For instance, for a field, the positions are:
	//    <0> Label <1> ":" <2> Expr <3> "," <4>
	Position int8
	List     []*Comment // len(List) > 0
}

func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() }
func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }

func (g *CommentGroup) Comments() []*CommentGroup { return nil }
func (g *CommentGroup) AddComment(*CommentGroup)  {}

func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }

func stripTrailingWhitespace(s string) string {
	i := len(s)
	for i > 0 && isWhitespace(s[i-1]) {
		i--
	}
	return s[0:i]
}

// Text returns the text of the comment.
// Comment markers (//, /*, and */), the first space of a line comment, and
// leading and trailing empty lines are removed. Multiple empty lines are
// reduced to one, and trailing space on lines is trimmed. Unless the result
// is empty, it is newline-terminated.
func (g *CommentGroup) Text() string {
	if g == nil {
		return ""
	}
	comments := make([]string, len(g.List))
	for i, c := range g.List {
		comments[i] = c.Text
	}

	lines := make([]string, 0, 10) // most comments are less than 10 lines
	for _, c := range comments {
		// Remove comment markers.
		// The parser has given us exactly the comment text.
		switch c[1] {
		case '/':
			//-style comment (no newline at the end)
			c = c[2:]
			// strip first space - required for Example tests
			if len(c) > 0 && c[0] == ' ' {
				c = c[1:]
			}
		case '*':
			/*-style comment */
			c = c[2 : len(c)-2]
		}

		// Split on newlines.
		cl := strings.Split(c, "\n")

		// Walk lines, stripping trailing white space and adding to list.
		for _, l := range cl {
			lines = append(lines, stripTrailingWhitespace(l))
		}
	}

	// Remove leading blank lines; convert runs of
	// interior blank lines to a single blank line.
	n := 0
	for _, line := range lines {
		if line != "" || n > 0 && lines[n-1] != "" {
			lines[n] = line
			n++
		}
	}
	lines = lines[0:n]

	// Add final "" entry to get trailing newline from Join.
	if n > 0 && lines[n-1] != "" {
		lines = append(lines, "")
	}

	return strings.Join(lines, "\n")
}

// An Attribute provides meta data about a field.
type Attribute struct {
	comments
	At   token.Pos
	Text string // must be a valid attribute format.
}

func (a *Attribute) Pos() token.Pos { return a.At }
func (a *Attribute) End() token.Pos { return a.At.Add(len(a.Text)) }

// A Field represents a field declaration in a struct.
type Field struct {
	comments
	Label    Label // must have at least one element.
	Optional token.Pos

	// No TokenPos: Value must be an StructLit with one field.
	TokenPos token.Pos
	Token    token.Token // ':' or '::', ILLEGAL implies ':'

	Value Expr // the value associated with this field.

	Attrs []*Attribute
}

func (d *Field) Pos() token.Pos { return d.Label.Pos() }
func (d *Field) End() token.Pos {
	if len(d.Attrs) > 0 {
		return d.Attrs[len(d.Attrs)-1].End()
	}
	return d.Value.End()
}

// TODO: make Alias a type of Field. This is possible now we have different
// separator types.

// An Alias binds another field to the alias name in the current struct.
type Alias struct {
	comments
	Ident *Ident    // field name, always an Ident
	Equal token.Pos // position of "="
	Expr  Expr      // An Ident or SelectorExpr
}

func (a *Alias) Pos() token.Pos { return a.Ident.Pos() }
func (a *Alias) End() token.Pos { return a.Expr.End() }

// A Comprehension node represents a comprehension declaration.
type Comprehension struct {
	comments
	Clauses []Clause // There must be at least one clause.
	Value   Expr     // Must be a struct
}

func (x *Comprehension) Pos() token.Pos { return x.Clauses[0].Pos() }
func (x *Comprehension) End() token.Pos {
	return x.Value.End()
}

// ----------------------------------------------------------------------------
// Expressions and types
//
// An expression is represented by a tree consisting of one
// or more of the following concrete expression nodes.

// A BadExpr node is a placeholder for expressions containing
// syntax errors for which no correct expression nodes can be
// created. This is different from an ErrorExpr which represents
// an explicitly marked error in the source.
type BadExpr struct {
	comments
	From, To token.Pos // position range of bad expression
}

// A BottomLit indicates an error.
type BottomLit struct {
	comments
	Bottom token.Pos
}

// An Ident node represents an left-hand side identifier.
type Ident struct {
	comments
	NamePos token.Pos // identifier position

	// This LHS path element may be an identifier. Possible forms:
	//  foo:    a normal identifier
	//  "foo":  JSON compatible
	//  <foo>:  a template shorthand
	Name string

	Scope Node // scope in which node was found or nil if referring directly
	Node  Node
}

// A TemplateLabel represents a field template declaration in a struct.
type TemplateLabel struct {
	comments
	Langle token.Pos
	Ident  *Ident
	Rangle token.Pos
}

// A BasicLit node represents a literal of basic type.
type BasicLit struct {
	comments
	ValuePos token.Pos   // literal position
	Kind     token.Token // INT, FLOAT, DURATION, or STRING
	Value    string      // literal string; e.g. 42, 0x7f, 3.14, 1_234_567, 1e-9, 2.4i, 'a', '\x7f', "foo", or '\m\n\o'
}

// A Interpolation node represents a string or bytes interpolation.
type Interpolation struct { // TODO: rename to TemplateLit
	comments
	Elts []Expr // interleaving of strings and expressions.
}

// A StructLit node represents a literal struct.
type StructLit struct {
	comments
	Lbrace token.Pos // position of "{"
	Elts   []Decl    // list of elements; or nil
	Rbrace token.Pos // position of "}"
}

// A ListLit node represents a literal list.
type ListLit struct {
	comments
	Lbrack token.Pos // position of "["
	Elts   []Expr    // list of composite elements; or nil
	Rbrack token.Pos // position of "]"
}

type Ellipsis struct {
	comments
	Ellipsis token.Pos // open list if set
	Type     Expr      // type for the remaining elements
}

// A ListComprehension node represents as list comprehension.
type ListComprehension struct {
	comments
	Lbrack  token.Pos // position of "["
	Expr    Expr
	Clauses []Clause  // Feed or Guard (TODO let)
	Rbrack  token.Pos // position of "]"
}

// A ForClause node represents a for clause in a comprehension.
type ForClause struct {
	comments
	For token.Pos
	Key *Ident // allow pattern matching?
	// TODO: change to Comma
	Colon  token.Pos
	Value  *Ident // allow pattern matching?
	In     token.Pos
	Source Expr
}

// A IfClause node represents an if guard clause in a comprehension.
type IfClause struct {
	comments
	If        token.Pos
	Condition Expr
}

// A ParenExpr node represents a parenthesized expression.
type ParenExpr struct {
	comments
	Lparen token.Pos // position of "("
	X      Expr      // parenthesized expression
	Rparen token.Pos // position of ")"
}

// A SelectorExpr node represents an expression followed by a selector.
type SelectorExpr struct {
	comments
	X   Expr   // expression
	Sel *Ident // field selector
}

// An IndexExpr node represents an expression followed by an index.
type IndexExpr struct {
	comments
	X      Expr      // expression
	Lbrack token.Pos // position of "["
	Index  Expr      // index expression
	Rbrack token.Pos // position of "]"
}

// An SliceExpr node represents an expression followed by slice indices.
type SliceExpr struct {
	comments
	X      Expr      // expression
	Lbrack token.Pos // position of "["
	Low    Expr      // begin of slice range; or nil
	High   Expr      // end of slice range; or nil
	Rbrack token.Pos // position of "]"
}

// A CallExpr node represents an expression followed by an argument list.
type CallExpr struct {
	comments
	Fun    Expr      // function expression
	Lparen token.Pos // position of "("
	Args   []Expr    // function arguments; or nil
	Rparen token.Pos // position of ")"
}

// A UnaryExpr node represents a unary expression.
type UnaryExpr struct {
	comments
	OpPos token.Pos   // position of Op
	Op    token.Token // operator
	X     Expr        // operand
}

// A BinaryExpr node represents a binary expression.
type BinaryExpr struct {
	comments
	X     Expr        // left operand
	OpPos token.Pos   // position of Op
	Op    token.Token // operator
	Y     Expr        // right operand
}

// token.Pos and End implementations for expression/type nodes.

func (x *BadExpr) Pos() token.Pos       { return x.From }
func (x *Ident) Pos() token.Pos         { return x.NamePos }
func (x *TemplateLabel) Pos() token.Pos { return x.Langle }
func (x *BasicLit) Pos() token.Pos      { return x.ValuePos }
func (x *Interpolation) Pos() token.Pos { return x.Elts[0].Pos() }
func (x *StructLit) Pos() token.Pos {
	if x.Lbrace == token.NoPos && len(x.Elts) > 0 {
		return x.Elts[0].Pos()
	}
	return x.Lbrace
}

func (x *ListLit) Pos() token.Pos           { return x.Lbrack }
func (x *Ellipsis) Pos() token.Pos          { return x.Ellipsis }
func (x *ListComprehension) Pos() token.Pos { return x.Lbrack }
func (x *ForClause) Pos() token.Pos         { return x.For }
func (x *IfClause) Pos() token.Pos          { return x.If }
func (x *ParenExpr) Pos() token.Pos         { return x.Lparen }
func (x *SelectorExpr) Pos() token.Pos      { return x.X.Pos() }
func (x *IndexExpr) Pos() token.Pos         { return x.X.Pos() }
func (x *SliceExpr) Pos() token.Pos         { return x.X.Pos() }
func (x *CallExpr) Pos() token.Pos          { return x.Fun.Pos() }
func (x *UnaryExpr) Pos() token.Pos         { return x.OpPos }
func (x *BinaryExpr) Pos() token.Pos        { return x.X.Pos() }
func (x *BottomLit) Pos() token.Pos         { return x.Bottom }

func (x *BadExpr) End() token.Pos { return x.To }
func (x *Ident) End() token.Pos {
	return x.NamePos.Add(len(x.Name))
}
func (x *TemplateLabel) End() token.Pos { return x.Rangle }
func (x *BasicLit) End() token.Pos      { return x.ValuePos.Add(len(x.Value)) }

func (x *Interpolation) End() token.Pos { return x.Elts[len(x.Elts)-1].Pos() }
func (x *StructLit) End() token.Pos {
	if x.Rbrace == token.NoPos && len(x.Elts) > 0 {
		return x.Elts[len(x.Elts)-1].Pos()
	}
	return x.Rbrace.Add(1)
}
func (x *ListLit) End() token.Pos { return x.Rbrack.Add(1) }
func (x *Ellipsis) End() token.Pos {
	if x.Type != nil {
		return x.Type.End()
	}
	return x.Ellipsis.Add(3) // len("...")
}
func (x *ListComprehension) End() token.Pos { return x.Rbrack }
func (x *ForClause) End() token.Pos         { return x.Source.End() }
func (x *IfClause) End() token.Pos          { return x.Condition.End() }
func (x *ParenExpr) End() token.Pos         { return x.Rparen.Add(1) }
func (x *SelectorExpr) End() token.Pos      { return x.Sel.End() }
func (x *IndexExpr) End() token.Pos         { return x.Rbrack.Add(1) }
func (x *SliceExpr) End() token.Pos         { return x.Rbrack.Add(1) }
func (x *CallExpr) End() token.Pos          { return x.Rparen.Add(1) }
func (x *UnaryExpr) End() token.Pos         { return x.X.End() }
func (x *BinaryExpr) End() token.Pos        { return x.Y.End() }
func (x *BottomLit) End() token.Pos         { return x.Bottom.Add(1) }

// ----------------------------------------------------------------------------
// Convenience functions for Idents

// NewIdent creates a new Ident without position.
// Useful for ASTs generated by code other than the Go
func NewIdent(name string) *Ident {
	return &Ident{comments{}, token.NoPos, name, nil, nil}
}

func (id *Ident) String() string {
	if id != nil {
		return id.Name
	}
	return "<nil>"
}

// ----------------------------------------------------------------------------
// Declarations

// An ImportSpec node represents a single package import.
type ImportSpec struct {
	comments
	Name   *Ident    // local package name (including "."); or nil
	Path   *BasicLit // import path
	EndPos token.Pos // end of spec (overrides Path.Pos if nonzero)
}

// Pos and End implementations for spec nodes.

func (s *ImportSpec) Pos() token.Pos {
	if s.Name != nil {
		return s.Name.Pos()
	}
	return s.Path.Pos()
}

// func (s *AliasSpec) Pos() token.Pos { return s.Name.Pos() }
// func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() }
// func (s *TypeSpec) Pos() token.Pos  { return s.Name.Pos() }

func (s *ImportSpec) End() token.Pos {
	if s.EndPos != token.NoPos {
		return s.EndPos
	}
	return s.Path.End()
}

// A BadDecl node is a placeholder for declarations containing
// syntax errors for which no correct declaration nodes can be
// created.
type BadDecl struct {
	comments
	From, To token.Pos // position range of bad declaration
}

// A ImportDecl node represents a series of import declarations. A valid
// Lparen position (Lparen.Line > 0) indicates a parenthesized declaration.
type ImportDecl struct {
	comments
	Import token.Pos
	Lparen token.Pos // position of '(', if any
	Specs  []*ImportSpec
	Rparen token.Pos // position of ')', if any
}

type Spec interface {
	Node
	specNode()
}

func (*ImportSpec) specNode() {}

func (*Package) specNode() {}

// An EmbedDecl node represents a single expression used as a declaration.
// The expressions in this declaration is what will be emitted as
// configuration output.
//
// An EmbedDecl may only appear at the top level.
type EmbedDecl struct {
	comments
	Expr Expr
}

// Pos and End implementations for declaration nodes.

func (d *BadDecl) Pos() token.Pos    { return d.From }
func (d *ImportDecl) Pos() token.Pos { return d.Import }
func (d *EmbedDecl) Pos() token.Pos  { return d.Expr.Pos() }

func (d *BadDecl) End() token.Pos { return d.To }
func (d *ImportDecl) End() token.Pos {
	if d.Rparen.IsValid() {
		return d.Rparen.Add(1)
	}
	if len(d.Specs) == 0 {
		return token.NoPos
	}
	return d.Specs[0].End()
}
func (d *EmbedDecl) End() token.Pos { return d.Expr.End() }

// ----------------------------------------------------------------------------
// Files and packages

// A File node represents a Go source file.
//
// The Comments list contains all comments in the source file in order of
// appearance, including the comments that are pointed to from other nodes
// via Doc and Comment fields.
type File struct {
	Filename string
	comments
	Decls []Decl // top-level declarations; or nil

	Imports    []*ImportSpec // imports in this file
	Unresolved []*Ident      // unresolved identifiers in this file
}

func (f *File) Pos() token.Pos {
	if len(f.Decls) > 0 {
		return f.Decls[0].Pos()
	}
	if f.Filename != "" {
		// TODO. Do something more principled and efficient.
		return token.NewFile(f.Filename, -1, 1).Pos(0, 0)
	}
	return token.NoPos
}

func (f *File) End() token.Pos {
	if n := len(f.Decls); n > 0 {
		return f.Decls[n-1].End()
	}
	return token.NoPos
}

// A Package represents a package clause.
type Package struct {
	comments
	PackagePos token.Pos // position of "package" pseudo-keyword
	Name       *Ident    // package name
}

func (p *Package) Pos() token.Pos {
	if p.PackagePos != token.NoPos {
		return p.PackagePos
	}
	if p.Name != nil {
		return p.Name.Pos()
	}
	return token.NoPos
}

func (p *Package) End() token.Pos {
	if p.Name != nil {
		return p.Name.End()
	}
	return token.NoPos
}
