/*
 * [The "BSD license"]
 *  Copyright (c) 2010 Terence Parr
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.antlr.tool;

import org.antlr.analysis.Label;
import org.antlr.runtime.Token;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class NameSpaceChecker {
	protected Grammar grammar;

	public NameSpaceChecker(Grammar grammar) {
		this.grammar = grammar;
	}

	public void checkConflicts() {
		for (int i = CompositeGrammar.MIN_RULE_INDEX; i < grammar.composite.ruleIndexToRuleList.size(); i++) {
			Rule r = grammar.composite.ruleIndexToRuleList.elementAt(i);
			if ( r==null ) {
				continue;
			}
			// walk all labels for Rule r
			if ( r.labelNameSpace!=null ) {
				Iterator it = r.labelNameSpace.values().iterator();
				while ( it.hasNext() ) {
					Grammar.LabelElementPair pair = (Grammar.LabelElementPair) it.next();
					checkForLabelConflict(r, pair.label);
				}
			}
			// walk rule scope attributes for Rule r
			if ( r.ruleScope!=null ) {
				List attributes = r.ruleScope.getAttributes();
				for (int j = 0; j < attributes.size(); j++) {
					Attribute attribute = (Attribute) attributes.get(j);
					checkForRuleScopeAttributeConflict(r, attribute);
				}
			}
			checkForRuleDefinitionProblems(r);
			checkForRuleArgumentAndReturnValueConflicts(r);
		}
		// check all global scopes against tokens
		Iterator it = grammar.getGlobalScopes().values().iterator();
		while (it.hasNext()) {
			AttributeScope scope = (AttributeScope) it.next();
			checkForGlobalScopeTokenConflict(scope);
		}
		// check for missing rule, tokens
		lookForReferencesToUndefinedSymbols();
	}

	protected void checkForRuleArgumentAndReturnValueConflicts(Rule r) {
		if ( r.returnScope!=null ) {
			Set conflictingKeys = r.returnScope.intersection(r.parameterScope);
			if (conflictingKeys!=null) {
				for (Iterator it = conflictingKeys.iterator(); it.hasNext();) {
					String key = (String) it.next();
					ErrorManager.grammarError(
						ErrorManager.MSG_ARG_RETVAL_CONFLICT,
						grammar,
						r.tree.getToken(),
						key,
						r.name);
				}
			}
		}
	}

	protected void checkForRuleDefinitionProblems(Rule r) {
		String ruleName = r.name;
		Token ruleToken = r.tree.getToken();
		int msgID = 0;
		if ( (grammar.type==Grammar.PARSER||grammar.type==Grammar.TREE_PARSER) &&
			 Character.isUpperCase(ruleName.charAt(0)) )
		{
			msgID = ErrorManager.MSG_LEXER_RULES_NOT_ALLOWED;
        }
        else if ( grammar.type==Grammar.LEXER &&
			      Character.isLowerCase(ruleName.charAt(0)) &&
			      !r.isSynPred )
		{
			msgID = ErrorManager.MSG_PARSER_RULES_NOT_ALLOWED;
        }
		else if ( grammar.getGlobalScope(ruleName)!=null ) {
			msgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
		}
		if ( msgID!=0 ) {
			ErrorManager.grammarError(msgID, grammar, ruleToken, ruleName);
		}
	}

	/** If ref to undefined rule, give error at first occurrence.
	 * 
	 *  Give error if you cannot find the scope override on a rule reference.
	 *
	 *  If you ref ID in a combined grammar and don't define ID as a lexer rule
	 *  it is an error.
	 */
	protected void lookForReferencesToUndefinedSymbols() {
		// for each rule ref, ask if there is a rule definition
		for (Iterator iter = grammar.ruleRefs.iterator(); iter.hasNext();) {
			GrammarAST refAST = (GrammarAST)iter.next();
			Token tok = refAST.token;
			String ruleName = tok.getText();
			Rule localRule = grammar.getLocallyDefinedRule(ruleName);
			Rule rule = grammar.getRule(ruleName);
			if ( localRule==null && rule!=null ) { // imported rule?
				grammar.delegatedRuleReferences.add(rule);
				rule.imported = true;
			}
			if ( rule==null && grammar.getTokenType(ruleName)!=Label.EOF ) {
				ErrorManager.grammarError(ErrorManager.MSG_UNDEFINED_RULE_REF,
										  grammar,
										  tok,
										  ruleName);
			}
        }
		if ( grammar.type==Grammar.COMBINED ) {
			// if we're a combined grammar, we know which token IDs have no
			// associated lexer rule.
			for (Iterator iter = grammar.tokenIDRefs.iterator(); iter.hasNext();) {
				Token tok = (Token) iter.next();
				String tokenID = tok.getText();
				if ( !grammar.composite.lexerRules.contains(tokenID) &&
					 grammar.getTokenType(tokenID)!=Label.EOF )
				{
					ErrorManager.grammarWarning(ErrorManager.MSG_NO_TOKEN_DEFINITION,
												grammar,
												tok,
												tokenID);
				}
			}
		}
		// check scopes and scoped rule refs
		for (Iterator it = grammar.scopedRuleRefs.iterator(); it.hasNext();) {
			GrammarAST scopeAST = (GrammarAST)it.next(); // ^(DOT ID atom)
			Grammar scopeG = grammar.composite.getGrammar(scopeAST.getText());
			GrammarAST refAST = (GrammarAST)scopeAST.getChild(1);
			String ruleName = refAST.getText();
			if ( scopeG==null ) {
				ErrorManager.grammarError(ErrorManager.MSG_NO_SUCH_GRAMMAR_SCOPE,
										  grammar,
										  scopeAST.getToken(),
										  scopeAST.getText(),
										  ruleName);
			}
			else {
				Rule rule = grammar.getRule(scopeG.name, ruleName);
				if ( rule==null ) {
					ErrorManager.grammarError(ErrorManager.MSG_NO_SUCH_RULE_IN_SCOPE,
											  grammar,
											  scopeAST.getToken(),
											  scopeAST.getText(),
											  ruleName);
				}
			}
		}
	}

	protected void checkForGlobalScopeTokenConflict(AttributeScope scope) {
		if ( grammar.getTokenType(scope.getName())!=Label.INVALID ) {
			ErrorManager.grammarError(ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE,
									  grammar, null, scope.getName());
		}
	}

	/** Check for collision of a rule-scope dynamic attribute with:
	 *  arg, return value, rule name itself.  Labels are checked elsewhere.
	 */
	public void checkForRuleScopeAttributeConflict(Rule r, Attribute attribute) {
		int msgID = 0;
		Object arg2 = null;
		String attrName = attribute.name;
		if ( r.name.equals(attrName) ) {
			msgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE;
			arg2 = r.name;
		}
		else if ( (r.returnScope!=null&&r.returnScope.getAttribute(attrName)!=null) ||
				  (r.parameterScope!=null&&r.parameterScope.getAttribute(attrName)!=null) )
		{
			msgID = ErrorManager.MSG_ATTRIBUTE_CONFLICTS_WITH_RULE_ARG_RETVAL;
			arg2 = r.name;
		}
		if ( msgID!=0 ) {
			ErrorManager.grammarError(msgID,grammar,r.tree.getToken(),attrName,arg2);
		}
	}

	/** Make sure a label doesn't conflict with another symbol.
	 *  Labels must not conflict with: rules, tokens, scope names,
	 *  return values, parameters, and rule-scope dynamic attributes
	 *  defined in surrounding rule.
	 */
	protected void checkForLabelConflict(Rule r, Token label) {
		int msgID = 0;
		Object arg2 = null;
		if ( grammar.getGlobalScope(label.getText())!=null ) {
			msgID = ErrorManager.MSG_SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE;
		}
		else if ( grammar.getRule(label.getText())!=null ) {
			msgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE;
		}
		else if ( grammar.getTokenType(label.getText())!=Label.INVALID ) {
			msgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_TOKEN;
		}
		else if ( r.ruleScope!=null && r.ruleScope.getAttribute(label.getText())!=null ) {
			msgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_SCOPE_ATTRIBUTE;
			arg2 = r.name;
		}
		else if ( (r.returnScope!=null&&r.returnScope.getAttribute(label.getText())!=null) ||
				  (r.parameterScope!=null&&r.parameterScope.getAttribute(label.getText())!=null) )
		{
			msgID = ErrorManager.MSG_LABEL_CONFLICTS_WITH_RULE_ARG_RETVAL;
			arg2 = r.name;
		}
		if ( msgID!=0 ) {
			ErrorManager.grammarError(msgID,grammar,label,label.getText(),arg2);
		}
	}

	/** If type of previous label differs from new label's type, that's an error.
	 */
	public boolean checkForLabelTypeMismatch(Rule r, Token label, int type) {
		Grammar.LabelElementPair prevLabelPair =
			(Grammar.LabelElementPair)r.labelNameSpace.get(label.getText());
		if ( prevLabelPair!=null ) {
			// label already defined; if same type, no problem
			if ( prevLabelPair.type != type ) {
				String typeMismatchExpr =
					Grammar.LabelTypeToString[type]+"!="+
					Grammar.LabelTypeToString[prevLabelPair.type];
				ErrorManager.grammarError(
					ErrorManager.MSG_LABEL_TYPE_CONFLICT,
					grammar,
					label,
					label.getText(),
					typeMismatchExpr);
				return true;
			}
		}
		return false;
	}
}
