/**
 * <copyright>
 *
 * Copyright (c) 2012 Willink Transformations and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     E.D.Willink - initial API and implementation
 *
 * </copyright>
 */
/*
	Convert a *.xtext file (CS resource) into an XBNF instance.
	
	Feature references are resolved to EStructuralFeature references.
	Cardinality is exposed as OneOrMore, ZeroOrOne, ZeroOrMore wrappers
	
Bugs:
	No support for enum rules, predicates 	
*/

modeltype XTEXT uses 'http://www.eclipse.org/2008/Xtext';
modeltype ECORE uses 'http://www.eclipse.org/emf/2002/Ecore';
modeltype XBNF uses 'http://www.eclipse.org/ocl/XBNF';
modeltype XBNFwc uses 'http://www.eclipse.org/ocl/XBNFwithCardinality';

transformation xtext2xbnf(in xtext : XTEXT, out XBNF);

main() {
	xtext.rootObjects()[XTEXT::Grammar]->map grammar2syntax();
}

mapping XTEXT::Grammar::grammar2syntax() : XBNF::Syntax {
	
/*	var selfRules : OrderedSet(AbstractRule) = self.rules;
	var selfRootElements : Set(AbstractElement) = selfRules.oclAsType(EObject).eAllContents().alternatives->asSet();
	var allElements : Set(AbstractElement) = selfRootElements->closure(if oclIsKindOf(CompoundElement) then oclAsType(CompoundElement).elements else null endif)->union(selfRootElements);
	var ruleCalls : Set(RuleCall) = allElements->select(oclIsKindOf(RuleCall)).oclAsType(RuleCall)->asSet();
	var ruleCalls : Set(RuleCall) = allElements->select(oclIsKindOf(RuleCall)).oclAsType(RuleCall)->asSet();
	var allRules : OrderedSet(AbstractRule) = ruleCalls.rule->asSet()->union(selfRules)->sortedBy(name);
	var lexerRules : Sequence(TypedRule) = allRules->reject(oclIsKindOf(ParserRule))->map typedRule2rule();
	var parserRules : Sequence(TypedRule) = allRules->select(oclIsKindOf(ParserRule))->map typedRule2rule(); */
	var allGrammars : Sequence(Grammar) = self->asSet()->closure(usedGrammars->asSet())->asSequence()->prepend(self);
	name := self.name;
--	var ruleCalls : Set(RuleCall) = self.oclAsType(EObject)->closure(eContents())->select(oclIsKindOf(RuleCall)).oclAsType(RuleCall)->asSet();
--	debug := XTEXT::Grammar.allInstances()->size().toString() + ' ' + ruleCalls->size().toString();
	grammars := allGrammars->iterate(g ; acc : Sequence(XBNF::Grammar) = Sequence{} | acc->append(g.map grammar2lexerGrammar())->append(g.map grammar2parserGrammar()));
}

/*query gatherRules(knownRules : Set(AbstractRule), candidateRules : Set(AbstractRule)) : Set(AbstractRule)
{
	var moreKnownRules = knownRules->union(candidateRules);
	var moreCalls : Set(RuleCall) = candidateRules.oclAsType(EObject)->closure(eContents().oclAsType(EObject)->asSet())->select(oclIsKindOf(RuleCall)).oclAsType(RuleCall)->asSet();
	var moreRules : Set(AbstractRule) = moreCalls.rule->asSet() - moreKnownRules;
	var t = object XBNF::ParserGrammar { name = 'test '; };
--	var t1 = object XBNF::ParserGrammar { name = 'test1 ' + knownRules->size().toString(); };
--	var t2 = object XBNF::ParserGrammar { name = 'test2 ' + knownRules->size().toString() + '/' + candidateRules->size().toString() + ' => ' + moreRules->size().toString(); };
	return moreKnownRules;
--	return if moreRules->isEmpty() then moreKnownRules else gatherRules(moreKnownRules, moreRules) endif;
}*/

mapping XTEXT::Grammar::grammar2lexerGrammar() : XBNF::LexerGrammar {
	var lexerRules : Sequence(TypedRule) = self.rules->reject(oclIsKindOf(ParserRule))->map typedRule2rule();
	name := self.name + 'Lexer';
	rules := lexerRules;
	goals := lexerRules->first()->asSequence();
}

mapping XTEXT::Grammar::grammar2parserGrammar() : XBNF::ParserGrammar {
	var parserRules : Sequence(TypedRule) = self.rules->select(oclIsKindOf(ParserRule))->map typedRule2rule();
--	var noRules : Set(AbstractRule) = Set{};
--	var allParserRules : Set(AbstractRule) = gatherRules(noRules, self.rules->first().oclAsType(AbstractRule)->asSet());
	name := self.name + 'Parser';
	rules := parserRules->sortedBy(name);
	goals := parserRules->first()->asSequence();
}

---------------------------------------------------------------------------------------
--	Map rule to rule
---------------------------------------------------------------------------------------
mapping XTEXT::AbstractRule::typedRule2rule() : XBNF::TypedRule 
disjuncts EnumRule::enumRule2rule,
ParserRule::parserRule2rule,
TerminalRule::terminalRule2rule
{}

abstract mapping XTEXT::AbstractRule::abstractRule2rule_base() : XBNF::TypedRule
{
	name := self.name;
	type := self.type.classifier;
	element := self.alternatives.element2element();
}

mapping XTEXT::EnumRule::enumRule2rule() : XBNF::TerminalRule
inherits AbstractRule::abstractRule2rule_base
{
	kind := 'EnumRule';
}

mapping XTEXT::ParserRule::parserRule2rule() : XBNF::ParserRule
inherits AbstractRule::abstractRule2rule_base
{
	kind := 'ParserRule';
}

mapping XTEXT::TerminalRule::terminalRule2rule() : XBNF::TerminalRule
inherits AbstractRule::abstractRule2rule_base
{
	kind := 'TerminalRule';
}

---------------------------------------------------------------------------------------
--	Map element to element
---------------------------------------------------------------------------------------
helper XTEXT::AbstractElement::element2element() : XBNF::AbstractElement
{
	return
	if self.cardinality = '?' then object ZeroOrOne { debug := self.cardinality; element := self.element2element2(); }
	else if self.cardinality = '+' then object OneOrMore { debug := self.cardinality; element := self.element2element2(); }
	else if self.cardinality = '*' then object ZeroOrMore { debug := self.cardinality; element := self.element2element2(); }
	else self.element2element2()
	endif
	endif
	endif;
}

helper XTEXT::AbstractElement::element2element2() : XBNF::AbstractElement
{
	return self.map abstractElement2element();
}

helper XTEXT::Assignment::element2element2() : XBNF::AbstractElement
{
	var theRule : AbstractRule = self.terminal.oclAsType(RuleCall).rule;
	var classifier : EClass = self.getClass();
	var feature : EStructuralFeature = classifier.eAllStructuralFeatures->select(s | (s.name = self.feature) or (s.name.toUpperCase() = ('is' + self.feature).toUpperCase()))->any(true);
	return self.terminal.map assignment2assignments(self, feature);
}

mapping XTEXT::AbstractElement::abstractElement2element() : XBNF::AbstractElement
disjuncts Action::action2element,
Alternatives::alternatives2element,
CharacterRange::characterRange2element,
CompoundElement::compoundElement2sequentialTerm,
EOF::eof2element,
EnumLiteralDeclaration::enumLiteralDeclaration2element,
Group::group2element,
Keyword::keyword2element,
NegatedToken::negatedToken2element,
RuleCall::ruleCall2element,
UnorderedGroup::unorderedGroup2element,
UntilToken::untilToken2element,
Wildcard::wildcard2element
{}

mapping XTEXT::Action::action2element() : XBNF::ActionAssignment
when { self.feature <> null }
{
	var classifier : EClass = self.type.classifier.oclAsType(EClass);
	debug := self.feature + ':' + classifier.name + self.operator + 'current';
	feature := classifier.eAllStructuralFeatures->select(s | (s.name = self.feature) or (s.name.toUpperCase() = ('is' + self.feature).toUpperCase()))->any(true);
	operator := self.operator;
	type := self.type.classifier;
}

mapping XTEXT::Alternatives::alternatives2element() : XBNFwc::Alternatives {
	debug := '|';
	elements := self.elements->element2element();
}

mapping XTEXT::CharacterRange::characterRange2element() : XBNF::CharacterRange {
	debug := '[' + self.left.value + '-' + self.right.value + ']';
	left := self.left.value;
	right := self.right.value;
}

mapping XTEXT::CompoundElement::compoundElement2sequentialTerm() : XBNFwc::Succession
{
	elements := self.elements->element2element();
}

mapping XTEXT::EOF::eof2element() : XBNF::EOF {
	debug := 'EOF';
}

mapping XTEXT::EnumLiteralDeclaration::enumLiteralDeclaration2element() : XBNF::RuleCall {
	debug := 'EnumLiteralDeclaration';
}

mapping XTEXT::Group::group2element() : XBNF::RuleCall {
	debug := 'Group';
}

mapping XTEXT::Keyword::keyword2element() : XBNF::Keyword {
	debug := '"' + self.value + '"';
	value := self.value;
}

mapping XTEXT::NegatedToken::negatedToken2element() : XBNF::NegatedToken {
	debug := 'NegatedToken';
	terminal := self.terminal.element2element();
}

mapping XTEXT::RuleCall::ruleCall2element() : XBNF::RuleCall {
	debug := self.rule.name;
	referredRule := self.rule.late resolveone(XBNF::AbstractRule);
}

mapping XTEXT::UnorderedGroup::unorderedGroup2element() : XBNF::RuleCall {
	debug := 'UnorderedGroup';
}

mapping XTEXT::UntilToken::untilToken2element() : XBNF::UntilToken {
	debug := 'UntilToken';
	terminal := self.terminal.element2element();
}

mapping XTEXT::Wildcard::wildcard2element() : XBNF::Wildcard {
	debug := 'Wildcard';
}

---------------------------------------------------------------------------------------
--	Map an Assignment.terminal to the appropriate assignnments
---------------------------------------------------------------------------------------
mapping XTEXT::AbstractElement::assignment2assignments(assignment : Assignment, theFeature : EStructuralFeature) : XBNF::AbstractElement
disjuncts Alternatives::alternatives2assignments,
CrossReference::crossReference2assignments,
Keyword::keyword2assignments,
RuleCall::ruleCall2assignments
{}

mapping XTEXT::Alternatives::alternatives2assignments(assignment : Assignment, theFeature : EStructuralFeature) : XBNFwc::Alternatives
{
	elements := self.elements->map assignment2assignments(assignment, theFeature);
}

mapping XTEXT::CrossReference::crossReference2assignments(assignment : Assignment, theFeature : EStructuralFeature) : XBNF::RuleCallAssignment
{
	var theRule : AbstractRule = self.terminal.oclAsType(RuleCall).rule;
	debug := '#1 ' + theFeature.name + assignment.operator + theRule.name;
	feature := theFeature;
	operator := assignment.operator;
	referredRule := theRule.late resolveone(XBNF::AbstractRule);
}

mapping XTEXT::Keyword::keyword2assignments(assignment : Assignment, theFeature : EStructuralFeature) : XBNF::KeywordAssignment
{
	debug := '"' + self.value + '"';
	feature := theFeature;
	operator := assignment.operator;
	value := self.value;
}

mapping XTEXT::RuleCall::ruleCall2assignments(assignment : Assignment, theFeature : EStructuralFeature) : XBNF::RuleCallAssignment
{
	debug := '#2 ' + theFeature.name + assignment.operator + self.rule.name;
	feature := theFeature;
	operator := assignment.operator;
	referredRule := self.rule.late resolveone(XBNF::AbstractRule);
}

---------------------------------------------------------------------------------------
--	Return the EClass that scopes feature assignments
---------------------------------------------------------------------------------------
query XTEXT::AbstractElement::getClass() : ECORE::EClass {
	var container : EObject = self.oclAsType(EObject).eContainer();
	return if container.oclIsKindOf(AbstractRule)
	then container.oclAsType(AbstractRule).type.classifier.oclAsType(EClass)
	else container.oclAsType(AbstractElement).getClass()
	endif
}

query XTEXT::CompoundElement::getClass() : ECORE::EClass {
	var container : EObject = self.oclAsType(EObject).eContainer();
	return if (self.elements->first().oclIsKindOf(Action))
	then self.elements->first().oclAsType(Action).type.classifier.oclAsType(EClass)
	else if container.oclIsKindOf(AbstractRule)
	then container.oclAsType(AbstractRule).type.classifier.oclAsType(EClass)
	else container.oclAsType(AbstractElement).getClass()
	endif endif
}
