package bento.sirius.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
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.util.Diagnostician;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import com.odesign.generator.Generate;
import com.odesign.generator.ModelGenerator;

@RunWith(Parameterized.class)
public class TestGraphicalBindingGenerator {

    @Parameters(name="{0}")
    public static Collection<Object> data() {
        return Arrays.asList(new Object[] {    
                t("resources/components/sequence/sequence-simple.odesign", 
                		"resources/components/graph/graph-model-1.xmi"),
                t("resources/components/graph/graph-simple.odesign",    
                		 "resources/components/sequence/sequence-model-1.xmi")
           });
    }

	private static Object t(String odesign, String... models) {
		return new TestData(odesign, models);
	}

	private static class TestData {
		private String odesign;
		private String[] models;

		public TestData(String odesign, String... models) {
			this.odesign = odesign;
			this.models = models;
		}
		
		public String getOdesign() {
			return odesign;
		}
		
		public String[] getModels() {
			return models;
		}
	}
	
	private File odesign;
	private String[] models;	
	
    public TestGraphicalBindingGenerator(TestData data) {
    	this.odesign = new File(data.getOdesign());
    	this.models = data.getModels();
    }
    
	@Test
	public void test() throws IOException {
		File testOutputs = new File("test-outputs");
		System.out.println("Testing: " + odesign.getAbsolutePath());
		
		Generate generate = new Generate();
		generate.GenerateOdesignMM(this.odesign.getAbsolutePath(), testOutputs);
		
		ResourceSet rs = new ResourceSetImpl();
		Resource mm = rs.getResource(URI.createFileURI(generate.getMetamodelGeneratedFile().getAbsolutePath()), true);
		
		assertEquals(1, mm.getContents().size());
		Diagnostic result = Diagnostician.INSTANCE.validate(mm.getContents().get(0));
		assertEquals(Diagnostic.OK, result.getCode());		
		
		// Uncomment and fix
		// TestSiriusValidity.assertOdesignValidity(generate.getOdesignGeneratedFile());
		
		EPackage originalPackage = generate.getOriginaleEPakage();
		EPackage generatedPackage = (EPackage) mm.getContents().get(0);
		
		File modelOutputs = testOutputs.toPath().resolve("models-" + originalPackage.getName()).toFile();
		if (! modelOutputs.exists()) {
			modelOutputs.mkdirs();
		}
		
		for (String model : models) {			
			testModel(model, originalPackage, generatedPackage, modelOutputs);
		}
	}

	private void testModel(String model, EPackage originalPackage, EPackage generatedPackage, File modelOutputs) throws FileNotFoundException, IOException {
		ResourceSet rs = new ResourceSetImpl();
		rs.getPackageRegistry().put(originalPackage.getNsURI(), originalPackage); // Just to be on the safe side
		
		Resource originalModel = rs.getResource(URI.createFileURI(model), true);
		
		ModelGenerator generator = new ModelGenerator(model, modelOutputs, originalPackage, generatedPackage);
		Resource generatedModel = generator.getGeneratedModel();
		
		List<EObject> originalObjects = TestUtils.getAllElements(originalModel);
		List<EObject> generatedObjects = TestUtils.getAllElements(generatedModel);
		
		// At least we put all objects in the target model
		assertTrue("Generated objects " + generatedObjects.size() + " is less than the original " + originalObjects.size(), 
				generatedObjects.size() >= originalObjects.size());		
	}

	
}

@@ -67,16 +67,62 @@
 Equals;%0A
+import static org.junit.Assert.assertNotNull;%0A
 import s
@@ -1279,27 +1279,33 @@
 ponents/
-graph/graph
+sequence/sequence
 -model-1
@@ -1426,33 +1426,27 @@
 ponents/
-sequence/sequence
+graph/graph
 -model-1
@@ -2377,24 +2377,27 @@
 puts);%0A%09%09%0A%09%09
+// 
 ResourceSet 
@@ -2422,24 +2422,27 @@
 etImpl();%0A%09%09
+// 
 Resource mm 
@@ -2546,50 +2546,153 @@
 ;%0A%09%09
-%0A%09%09assertEquals(1, mm.getContents().size()
+EPackage originalPackage = generate.getOriginaleEPakage();%0A%09%09EPackage generatedPackage = generate.getEpack();%0A%09%09%0A%09%09assertNotNull(generatedPackage
 );%0A%09
@@ -2744,39 +2744,32 @@
 alidate(
-mm.getContents().get(0)
+generatedPackage
 );%0A%09%09ass
@@ -2930,135 +2930,8 @@
 %0A%09%09%0A
-%09%09EPackage originalPackage = generate.getOriginaleEPakage();%0A%09%09EPackage generatedPackage = (EPackage) mm.getContents().get(0);%0A
 %09%09%0A%09
@@ -3143,21 +3143,31 @@
 stModel(
+new File(
 model
+)
 , origin
@@ -3242,22 +3242,20 @@
 stModel(
-String
+File
  model, 
@@ -3416,118 +3416,8 @@
 ();%0A
-%09%09rs.getPackageRegistry().put(originalPackage.getNsURI(), originalPackage); // Just to be on the safe side%0A%09%09%0A
 %09%09Re
@@ -3477,16 +3477,34 @@
 RI(model
+.getAbsolutePath()
 ), true)
@@ -3561,16 +3561,34 @@
 or(model
+.getAbsolutePath()
 , modelO
@@ -4086,8 +4086,9 @@
 %09%7D%0A%0A%09%0A%7D%0A
+%0A

Fix bug in the specification of the input models