package de.ugoe.cs.swe.bnftools.validation;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.xtext.EcoreUtil2;
import de.ugoe.cs.swe.bnftools.ebnf.Atom;
import de.ugoe.cs.swe.bnftools.ebnf.DefinitionList;
import de.ugoe.cs.swe.bnftools.ebnf.EtsiBnf;
import de.ugoe.cs.swe.bnftools.ebnf.Rule;
import de.ugoe.cs.swe.bnftools.ebnf.RuleReference;
import de.ugoe.cs.swe.bnftools.ebnf.SingleDefinition;
import de.ugoe.cs.swe.bnftools.ebnf.Term;

public class EbnfAnalysisUtils {

	//----------------------------------------------------------------------------------------------------

	static public boolean isPassthroughRule(Rule rule) {
		DefinitionList definitionList = rule.getDefinitionList();
		if (definitionList == null)
			return false;
		
		if (rule.getDefinitionList().getSingleDefinition().size() == 1) {
			SingleDefinition element = rule.getDefinitionList().getSingleDefinition().get(0);
			if (element.getTerms().size() == 1) {
				Term first = element.getTerms().get(0);
				if (first.getTermAtom() != null) {
					Atom atom = (Atom) first.getTermAtom();
					if (atom.getAtomRuleReference() != null)
						return true;
				}
			}
		}

		return false;
	}


	
	//----------------------------------------------------------------------------------------------------

	static public boolean isTokenRule(Rule rule) {
		DefinitionList definitionList = rule.getDefinitionList();
		if (definitionList == null)
			return false;
		
		if (rule.getDefinitionList().getSingleDefinition().size() == 1) {
			SingleDefinition element = rule.getDefinitionList().getSingleDefinition().get(0);
			if (element.getTerms().size() == 1) {
				Term first = element.getTerms().get(0);
				Atom atom = first.getTermAtom();
				if (atom != null && atom.getAtomStringRule() != null)  {
					return true;
				}
			}
		}

		return false;
	}



	//----------------------------------------------------------------------------------------------------

	static public List<RuleReference> findReferences(Rule rule) {
		List<RuleReference> ruleReferences = new ArrayList<RuleReference>();
		EtsiBnf bnf = (EtsiBnf) rule.eContainer().eContainer();

		List<RuleReference> rules = EcoreUtil2.getAllContentsOfType(bnf, RuleReference.class);
		for (RuleReference r : rules) {
			if(r.getRuleref().getName().equals(rule.getName())){
				ruleReferences.add(r);
			}
		}
		
		return ruleReferences;
	}

	//----------------------------------------------------------------------------------------------------
	public static List<Rule> getAllRules(EtsiBnf bnf){
		List<Rule> rules = EcoreUtil2.getAllContentsOfType(bnf, Rule.class);
		return rules;
	}
}
