// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package parser

import (
	"fmt"
	"mojom/mojom_parser/lexer"
	"mojom/mojom_parser/mojom"
	"strings"
)

///////////////////////////////////////////////////////////////////////
/// Type Parser
/// //////////////////////////////////////////////////////////////////

// This file contains the definition of the Parser type but it does not contain
// the actual parsing logic. That may be found in parsing.go

// A Parser is constructed and used to parse a single mojom file. The
// Parser is given a pointer to a MojomDescriptor that it will populate.
// The same MojomDescriptor may be given to successive runs of the Parser
// so that an entire graph of .mojom files may be parsed.
type Parser struct {
	// The stream of input tokens
	inputStream lexer.TokenStream

	// The current error state. In the current generation of the Parser we
	// only handle a single parse error before giving up. If an error
	// has been encountered then |err| is not nil.
	// TODO(rudominer) Enhancement: Parser should be able to keep going
	// after some errors. Change this field to be a list of errors instead of
	// a single error.
	err *ParseError

	// Last token seen, whether or not it was consumed.
	lastSeen lexer.Token

	// Last token consumed. May or may not be equal to lastSeen.
	lastConsumed lexer.Token

	// The root of the parse tree being constructed. This may be nil
	// because the parse tree is only explicitly constructed in
	// debug mode.
	rootNode *ParseNode

	// The current node of the parse tree in our recursive descent. This
	// may be nil because the parse tree is only explicitly constructed fo
	// in debug mode.
	currentNode *ParseNode

	// The MojomDescriptor being filled in by the Parser. This is passed
	// in in the constructor.
	mojomDescriptor *mojom.MojomDescriptor

	// The Parser creates a new instance of MojomFile on each call to Parse(),
	// which may only be called once per instance.
	mojomFile *mojom.MojomFile

	// The top of the Scope stack.
	currentScope *mojom.Scope

	debugMode bool
	used      bool
}

// Make a new Parser in preparation for calling Parse().
func MakeParser(fileName, fileContents string,
	descriptorToPopulate *mojom.MojomDescriptor) Parser {
	if descriptorToPopulate == nil {
		panic("descriptorToPopulate must not be nil")
	}
	inputStream := lexer.Tokenize(fileContents)
	parser := Parser{inputStream: inputStream,
		mojomDescriptor: descriptorToPopulate}
	parser.mojomDescriptor = descriptorToPopulate
	parser.mojomFile = parser.mojomDescriptor.AddMojomFile(fileName)
	return parser
}

func (p *Parser) SetDebugMode(debug bool) {
	p.debugMode = debug
}

// Perform the parsing on the |fileContents| passed to MakeParser().
// The |descriptorToPopulate| passed to MakeParser() will be populated.
// After Parse() is done call GetMojomFile() to get the resulting
// |MojomFile|. The |Imports| field of that |MojomFile| gives the
// files imported by the file that was just parsed. For each file |f|
// in |Imports|, call MojomDescriptor.ContainsFile(f) on
// |descriptorToPopulate| to determine whether or not |f| has already
// been parsed. If not then construct another Parser for |f| and its
// contents and call Parse() again.
func (p *Parser) Parse() {
	if p.used {
		panic("An instance of Parser may only be used once.")
	}
	p.used = true

	// Perform the recursive descent.
	// TODO(rudominer) This will be uncommented in a later CL.
	// p.parseMojomFile()

	// Check if there are any extraneous tokens left in the stream.
	if p.OK() && !p.checkEOF() {
		token := p.peekNextToken("")
		message := fmt.Sprintf("Extraneous token at %s: %v.",
			token.LongLocationString(), token)
		p.err = &ParseError{ParserErrorCodeExtraneousToken, message}
	}
}

// After Parse() is done call this method to obtain the resulting
// MojomFile.
func (p *Parser) GetMojomFile() *mojom.MojomFile {
	return p.mojomFile
}

// Returns the root of the parse tree if this Parser is in debug mode.
// Otherwise returns nil.
func (p *Parser) GetParseTree() *ParseNode {
	return p.rootNode
}

////////////////////////////////////////////////////////////////////////////
// Parse Error Handling
////////////////////////////////////////////////////////////////////////////

type ParseError struct {
	code    ParseErrorCode
	message string
}

// Make ParseError implement the error interface.
func (e ParseError) Error() string {
	return e.message
}

// Returns whether or not the Parser is in a non-error state.
func (p *Parser) OK() bool {
	return p.err == nil
}

// Returns the current ParseError or nil if OK() is true.
func (p *Parser) GetError() *ParseError {
	return p.err
}

//////////// Error codes //////////
type ParseErrorCode int

const (
	// An attributes section appeared in a location it is not allowed.
	ParserErrorCodeBadAttributeLocation = iota

	// Two types or values with the same fully qualified name were declared.
	ParserErrorCodeDuplicateDeclaration

	// Unexpected end-of-file
	ParserErrorCodeEOF

	// A simple name was expected but an identifier contained a dot.
	ParserErrorCodeExpectedSimpleName

	// After what appears to be a complete mojom file there were extra tokens.
	ParserErrorCodeExtraneousToken

	// An integer literal value was too large
	ParserErrorCodeIntegerOutOfRange

	// An integer literal value was ill-formed.
	// TODO(azani) This is only necessary because the lexer allows some
	// illegal tokens such as "0x"
	ParserErrorCodeIntegerParseError

	// A semicolon was missing.
	// TODO(rudominer) Consider elimintating most semicolons from the language.
	ParserErrorCodeMissingSemi

	// The type of a value is not compatible with the type of the variable
	// to which it is being assigned.
	ParserErrorCodeNotAssignmentCompatible

	// An unexpected token was encountered. This is the most common error.
	ParserErrorCodeUnexpectedToken
)

////////////////////////////////////////////////////////////////////////////
// Methods for accessing the stream of tokens.
////////////////////////////////////////////////////////////////////////////

// Returns the next available token in the stream without advancing the
// stream cursor. In case the stream cursor is already past the end
// the returned Token will be the EOF token. In this case the global
// error state will be set to ParserErrorCodeEOF error code with the message
// "Unexpected end-of-file " concatenated with |eofMessage|. In case of
// any other type of error the returned token is unspecified and the
// global error state will be set with more details.
func (p *Parser) peekNextToken(eofMessage string) (nextToken lexer.Token) {
	nextToken = p.inputStream.PeekNext()
	if nextToken.EOF() {
		errorMessage := "Unexpected end-of-file. " + eofMessage
		p.err = &ParseError{ParserErrorCodeEOF, errorMessage}
	}
	p.lastSeen = nextToken
	return
}

// This method is similar to peekNextToken except that in the case of EOF
// it does not set the global error state but rather returns |eof| = |true|.
// This method is useful when EOF is an allowed state and you want
// to know what the extraneous token is in case it is not EOF.
func (p *Parser) checkEOF() (eof bool) {
	p.lastSeen = p.inputStream.PeekNext()
	eof = p.lastSeen.EOF()
	return
}

// Sets p.lastConsumed to the value of the next available token in the
// stream and then advances the stream cursor. If the cursor is already
// past the end of the stream then it sets p.lastConsumed to the EOF
// token.
func (p *Parser) consumeNextToken() {
	p.lastConsumed = p.inputStream.PeekNext()
	p.inputStream.ConsumeNext()
}

////////////////////////////////////////////////////////////////////////////
// Parse Tree Support
////////////////////////////////////////////////////////////////////////////

// In normal operation we do not explicit construct a parse tree. This is
// only used in debug mode.

///// ParseNode type /////
type ParseNode struct {
	name     string
	tokens   []*lexer.Token
	parent   *ParseNode
	children []*ParseNode
}

func (node *ParseNode) String() string {
	return toString(node, 0)
}

// Recursively generates a string representing a tree of nodes
// where indentLevel indicates the level in the tree
func toString(node *ParseNode, indentLevel int) string {
	prefix := "\n" + strings.Repeat(".", indentLevel) + "^"
	firstTokens := ""
	if node.tokens != nil {
		firstTokens = fmt.Sprintf("%s", node.tokens)
	}
	s := fmt.Sprintf("%s%s%s", prefix, node.name, firstTokens)
	if node.children != nil {
		for _, child := range node.children {
			s += toString(child, indentLevel+3)
		}
	}
	return s
}

func newParseNode(name string) *ParseNode {
	node := new(ParseNode)
	node.name = name
	return node
}

func (node *ParseNode) appendChild(name string, firstToken *lexer.Token) *ParseNode {
	child := newParseNode(name)
	child.tokens = append(child.tokens, firstToken)
	child.parent = node
	node.children = append(node.children, child)
	return child
}

func (p *Parser) pushRootNode(name string) {
	if !p.debugMode {
		return
	}
	p.rootNode = newParseNode(name)
	p.currentNode = p.rootNode
}

func (p *Parser) pushChildNode(name string) {
	if p.currentNode != nil {
		tokenCopy := p.lastSeen
		childNode := p.currentNode.appendChild(name, &(tokenCopy))
		p.currentNode = childNode
	}
}

func (p *Parser) attachToken() {
	if p.currentNode != nil {
		tokenCopy := p.lastSeen
		p.currentNode.tokens = append(p.currentNode.tokens, &tokenCopy)
	}
}

func (p *Parser) popNode() {
	if p.currentNode != nil {
		p.currentNode = p.currentNode.parent
	}
}
