/**
 * Copyright (c) 2009, 2011, 2012 Borland Software Corporation & others
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Artem Tikhomirov (Borland) - initial API and implementation
 *    Guillaume Hillairet (Montages A.G.)
 */
library Audits;
 
import Utils;
import Mappings;
import gmf.GenModelAccess;

modeltype GMFMAP uses mappings('http://www.eclipse.org/gmf/2006/mappings');
modeltype GMFTOOL uses tooldef('http://www.eclipse.org/gmf/2005/ToolDefinition');
modeltype GMFGEN uses gmfgen('http://www.eclipse.org/gmf/2009/GenModel');
modeltype GMFGRAPH uses gmfgraph('http://www.eclipse.org/gmf/2006/GraphicalDefinition');
modeltype ECORE uses ecore('http://www.eclipse.org/emf/2002/Ecore');
modeltype GENMODEL uses genmodel('http://www.eclipse.org/emf/2002/GenModel');

-- 
-- Audits
-- 

mapping GMFMAP::AuditContainer::audits() : GMFGEN::GenAuditRoot {
	result.categories += self.allContainers().map category();
	result.rules += self.allContainers().audits.map rule();
	
	var allRulesWithContext := result.rules->select(not target.oclIsUndefined());
	var rulesWithDiagramElementTarget := allRulesWithContext->select(target.oclIsTypeOf(GMFGEN::GenDiagramElementTarget));
	rulesWithDiagramElementTarget.target[GMFGEN::GenDiagramElementTarget]->forEach(t) {
		-- Basically, all rules with targets != null
		-- get a context (emf.validation), which is a scope or set of elements audit is evaluated against.
		-- For certain cases, e.g. diagram elements as audit targets, special logic to select these
		-- elements should get generated - to filter diagram views by visualID, and hence
		-- there's another implementation of IClientSelector and dedicated context.
		var ctx : GMFGEN::GenAuditContext;
		-- use of exists seems to be sufficient, as all ruleTargets for a given context should get same elements
		-- by the nature of construction. However, more honest way would be to use forAll, accompanied with not isEmpty():
		-- not cc.ruleTargets[GMFGEN::GenDiagramElementTarget]->isEmpty() and cc.ruleTargets[...]->forAll(element = t.element) 
		ctx := result.clientContexts->selectOne(cc | cc.ruleTargets[GMFGEN::GenDiagramElementTarget]->exists(element = t.element));
		-- there might be already a context to pick same elements this target has 
		if ctx.oclIsUndefined() then {
			ctx := object GMFGEN::GenAuditContext {
				id := t.element.visualID.repr()->asList()->joinfields('_','Ctx_','')
			};
			result.clientContexts += ctx;
		} endif;
		t.contextSelector := ctx;
	};
	var defaultAuditContext := object GMFGEN::GenAuditContext {};
	result.clientContexts += defaultAuditContext;
	(allRulesWithContext - rulesWithDiagramElementTarget).target->forEach(t) { t.contextSelector := defaultAuditContext };
}

mapping GMFMAP::AuditContainer::category() : GMFGEN::GenAuditContainer {
	id := self.id;
	name := self.name;
	description := self.description;
	path += self.parentContainer.resolveone(GMFGEN::GenAuditContainer).path;
	-- alternative, not sure which one is better: 
	-- path += self.parentContainer.map category().path;
	path += result;
}

mapping GMFMAP::AuditRule::rule() : GMFGEN::GenAuditRule {
	id := self.id;
	name := self.name;
	message := self.message;
	description := self.description;
	useInLiveMode := self.useInLiveMode;
	target := self.target.map auditTarget();
	rule := self.rule.map createConstraint();
	severity := self.severity.severity();
	category := self.container.map category();
}

mapping GMFMAP::Auditable::auditTarget() : GMFGEN::GenAuditable  
	disjuncts 
		GMFMAP::DomainElementTarget::ruleTarget, 
		GMFMAP::NotationElementTarget::ruleTarget, 
		GMFMAP::DiagramElementTarget::ruleTarget,
		GMFMAP::AuditedMetricTarget::ruleTarget, 
		GMFMAP::DomainAttributeTarget::ruleTarget
	{} --assert (false) with log ('Unknown rule target', self);
	
mapping GMFMAP::DomainElementTarget::ruleTarget() : GMFGEN::GenDomainElementTarget {
	element := self.element.findGenClass();
}

mapping GMFMAP::NotationElementTarget::ruleTarget() : GMFGEN::GenNotationElementTarget {
	element := self.element.findGenClass(); -- XXX double-check if domain's genmodel should be consulted here, not notation's
}

mapping GMFMAP::DiagramElementTarget::ruleTarget() : GMFGEN::GenDiagramElementTarget {
	-- alternatives:
	if self.element.oclIsKindOf(LinkMapping) then {
		element += self.element.oclAsType(LinkMapping).map structure();
	} else if self.element.oclIsKindOf(NodeMapping) then {
		var el := self.element.container();
		if el.oclIsKindOf(TopNodeReference) then
			element += el.oclAsType(TopNodeReference).map structure()
		else
			element += el.oclAsType(ChildReference).map structure(self.element.oclAsType(NodeMapping)) 
		endif
	} endif
	endif;
--	element += self.element.resolveIn(GMFMAP::NodeMapping::structure, GMFGEN::GenCommonBase);
--	element += self.element.resolveIn(GMFMAP::LinkMapping::structure, GMFGEN::GenCommonBase);
--	element += self.element.resolveIn(GMFMAP::TopNodeReference::structure, GMFGEN::GenCommonBase);
--	element += self.element.resolve(GMFGEN::GenCommonBase);
}

mapping GMFMAP::AuditedMetricTarget::ruleTarget() : GMFGEN::GenAuditedMetricTarget {
	result.metric := self.metric.map rule();
	var resultClassifier := loadEcoreGenModel().genPackages->first().genClassifiers[GENMODEL::GenDataType]->selectOne(ecoreDataType.name='EDoubleObject');
	assert (not resultClassifier.oclIsUndefined()) with log ('Troubles loading ecore.genmodel and accessing EDoubleObject');
	result.metricValueContext := resultClassifier;
}

mapping GMFMAP::DomainAttributeTarget::ruleTarget() : GMFGEN::GenDomainAttributeTarget {
	attribute := self.attribute.findGenFeature();
	nullAsError := self.nullAsError;
}

-- 
-- Metrics
-- 

mapping GMFMAP::MetricContainer::metrics() : GMFGEN::GenMetricContainer {
	metrics += self.metrics.map rule();
}

mapping GMFMAP::MetricRule::rule() : GMFGEN::GenMetricRule {
	key := self.key;
	name := self.name;
	description := self.description;
	lowLimit := self.lowLimit;
	highLimit := self.highLimit;
	rule := self.rule.map createValueExpression();
	target := self.target.map metricTarget();
}

mapping GMFMAP::Measurable::metricTarget() : GMFGEN::GenMeasurable
	disjuncts 
		GMFMAP::DomainElementTarget::ruleTarget, 
		GMFMAP::NotationElementTarget::ruleTarget, 
		GMFMAP::DiagramElementTarget::ruleTarget
	{} --assert (false) with log ('Unknown rule target', self);
	
--
--	Queries
--

query GMFMAP::AuditContainer::allContainers() : Sequence(GMFMAP::AuditContainer) =
	self.childContainers.allContainers()->flatten()->prepend(self);
	
query GMFMAP::Severity::severity() : GMFGEN::GenSeverity =
	switch  {
		case (self = GMFMAP::Severity::INFO) return GMFGEN::GenSeverity::INFO;
		case (self = GMFMAP::Severity::WARNING) return GMFGEN::GenSeverity::WARNING;
		case (self = GMFMAP::Severity::ERROR) return GMFGEN::GenSeverity::ERROR;
		else return null;
	};
