pre {
	var configuration = new FED!Configuration();
}

post {
	configuration.features = configuration.features.sortBy(f|f.name);
}

rule Feature2Feature 
	transform s : XML!t_feature
	to t : FED!Feature {
	
	configuration.features.add(t);
	t.name = s.a_id;
	t.plugins = s.c_plugin.equivalent().sortBy(p|p.name);
	
	t.includes = s.includes().equivalent();
	
	t.pluginDependencies = s.plugin_dependencies().sortBy(p|p.name);
	t.depends = s.dependencies().equivalent().sortBy(d|d.name);
}

rule Plugin2Plugin
	transform s : XML!t_plugin
	to t: FED!Plugin {

	t.name = s.a_id;	
}

operation t_feature includes() : Collection(t_feature) {
	var includes = self.c_includes;
	var included_feature_names = includes.collect(a|a.a_id);
	var included_features = included_feature_names.collect(name|t_feature.all.selectOne(f|f.a_id == name));
	
	return included_features.asSet();
}

operation t_feature plugin_dependencies() : Collection(FED!Plugin) {
	var requires = self.e_requires;
	
	if (requires.isDefined()) {
		var required_plugin_names = requires.children.collect(i|i.a_plugin);
		var required_plugins = required_plugin_names.collect(name|find_or_create_plugin(name));
	
		return required_plugins.asSet();
	
	} else {
		return Set{};
	}
}

operation find_or_create_plugin(name : String) : FED!Plugin {
	var plugin = t_plugin.all.selectOne(p|p.a_id == name);
	
	if (plugin.isDefined()) {
		plugin = plugin.equivalent();
	
	} else {
		plugin = new FED!Plugin;
		plugin.name = name;
		configuration.plugins.add(plugin);
	}
	
	return plugin;
}

operation t_feature dependencies() : Collection(t_feature) {
	var requires = self.e_requires;
	
	if (requires.isDefined()) {
		var required_plugins = requires.children.collect(i|i.a_plugin);
		var required_features = required_plugins.collect(p|features_for(p)).flatten();
	
		return required_features.asSet();
	
	} else {
		return Set{};
	}
}

operation features_for(plugin_id : String) : Collection(t_feature) {
	return t_feature.all.select(f|f.contains(plugin_id));
}

operation t_feature contains(plugin_id : String) : Boolean {
	return self.c_plugin.exists(a|a.a_id == plugin_id);
}