package anatlyzer.atl.tests.api;

import java.util.ArrayList;
import java.util.HashMap;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;

import anatlyzer.atl.analyser.Analyser;
import anatlyzer.atl.analyser.AnalysisResult;
import anatlyzer.atl.analyser.namespaces.GlobalNamespace;
import anatlyzer.atl.model.ATLModel;
import anatlyzer.atl.model.ATLModelTrace;

public class AnalysisLoader {

	private GlobalNamespace globalNamespace;
	private ATLModel atlTransformation;

	public static AnalysisLoader fromResource(Resource trafo, Object[] metamodels, String[] names) {
		AnalysisLoader result = new AnalysisLoader();
		
		result.globalNamespace = createNamespace(metamodels, names);
		result.atlTransformation = new ATLModel(trafo, trafo.getURI().toFileString(), true);		
		
		return result;
	}

	public static GlobalNamespace createNamespace(Object[] metamodels, String[] names) {
		ResourceSet rs = new ResourceSetImpl();
		int i = 0;
		HashMap<String, Resource> logicalNamesToResources = new HashMap<String, Resource>();
		ArrayList<Resource> resources = new ArrayList<Resource>();
		for (Object fileOrResource : metamodels) {
			Resource r = null;
			if (fileOrResource instanceof String) {
				r = rs.getResource(URI.createURI((String) fileOrResource), true);
			} else {
				r = (Resource) fileOrResource;
			}
			resources.add(r);
			logicalNamesToResources.put(names[i], r);
			i++;
		}
		
		return new GlobalNamespace(resources, logicalNamesToResources);
	}
	
	

	public static AnalysisLoader fromATLModel(ATLModel trafo, Object[] metamodels, String[] names) {
		AnalysisLoader result = new AnalysisLoader();
		
		ResourceSet rs = new ResourceSetImpl();
		int i = 0;
		HashMap<String, Resource> logicalNamesToResources = new HashMap<String, Resource>();
		ArrayList<Resource> resources = new ArrayList<Resource>();
		for (Object fileOrResource : metamodels) {
			Resource r = null;
			if (fileOrResource instanceof String) {
				r = rs.getResource(URI.createURI((String) fileOrResource), true);
				if ( r == null )
					throw new IllegalStateException();
			} else {
				r = (Resource) fileOrResource;
			}
			resources.add(r);
			logicalNamesToResources.put(names[i], r);
			i++;
		}

		result.globalNamespace = new GlobalNamespace(resources, logicalNamesToResources);		
		result.atlTransformation = trafo;		
		
		return result;
	}

	public ATLModelTrace getTrace() {
		return this.atlTransformation.getTrace();
	}
	
	public AnalysisResult analyse() {
		Analyser analyser = new Analyser(globalNamespace, atlTransformation);
		analyser.perform();
		return new AnalysisResult(analyser);		
	}
	
	public GlobalNamespace getNamespace() {
		return globalNamespace;
	}
	
	public ATLModel getAtlTransformation() {
		return atlTransformation;
	}
	
	public static void setStandaloneMode() {
		// This is needed for the copier, which uses this special extension...
		Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("ext", new XMIResourceFactoryImpl());
	}
	
}

@@ -566,16 +566,72 @@
 elTrace;
+%0Aimport anatlyzer.atl.tests.api.AtlLoader.LoadException;
 %0A%0Apublic
@@ -735,16 +735,362 @@
 ation;%0A%0A
+%09public static AnalysisLoader fromFilename(String trafoFilename, Object%5B%5D metamodels, String%5B%5D names) throws LoadException %7B%0A%09%09Resource atlTrafo = AtlLoader.load(trafoFilename);%0A%09%09AnalysisLoader loader = fromResource(atlTrafo, metamodels, names);%0A%09%09return loader;%0A%09%7D%0A%09%0A%09/**%0A%09 * You can use AtlLoader to get a resource from a transformation.%0A%09 */%0A
 %09public 

Add facility to analysis loader