// 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 (*StructComprehension) 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 (*ComprehensionDecl) declNode() {}
func (*ImportDecl) declNode()        {}
func (*BadDecl) declNode()           {}
func (*EmbedDecl) declNode()         {}
func (*Alias) 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 colon: Value must be an StructLit with one field.
	Colon token.Pos
	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()
}

// 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 ComprehensionDecl node represents a field comprehension.
type ComprehensionDecl struct {
	comments
	Field   *Field
	Select  token.Pos
	Clauses []Clause
}

func (x *ComprehensionDecl) Pos() token.Pos { return x.Field.Pos() }
func (x *ComprehensionDecl) End() token.Pos {
	if len(x.Clauses) > 0 {
		return x.Clauses[len(x.Clauses)-1].End()
	}
	return x.Select
}

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