package uk.org.taverna.scufl2.api.common;

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

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import uk.org.taverna.scufl2.api.container.WorkflowBundle;
import uk.org.taverna.scufl2.api.io.TestWorkflowBundleIO;

public class TestAbstractCloneable {
	private WorkflowBundle originalWfBundle;
	private List<WorkflowBean> originalBeans;

	@Before
	public void makeExampleWorkflow() {
		originalWfBundle = new TestWorkflowBundleIO().makeWorkflowBundle();
		originalBeans = AllBeansVisitor.allBeansFrom(originalWfBundle);		
	}

	@Test
	public void megaClone() throws Exception {
		AbstractCloneable clone = originalWfBundle.clone();
//		AbstractCloneable clone = originalWfBundle;
		
		
		List<WorkflowBean> stillOriginalBeans = AllBeansVisitor.allBeansFrom(originalWfBundle);
		System.out.println(stillOriginalBeans);
		assertEquals(originalBeans.size(), stillOriginalBeans.size());
		// All original beans should be identical
		assertEquals(originalBeans.size(), findCommonById(originalBeans, stillOriginalBeans).size());
		
		
		List<WorkflowBean> clonedBeans = AllBeansVisitor.allBeansFrom(clone);
		List<WorkflowBean> common = findCommonById(originalBeans, clonedBeans);
		assertTrue("Found some common beans: " + common, common.isEmpty());
//		
		// Check parents are present
		checkParents(originalBeans);
		checkParents(stillOriginalBeans);
		checkParents(clonedBeans);
	}

	private void checkParents(List<WorkflowBean> beans) {
		for (WorkflowBean b : beans) {
			if (b instanceof Child) {
				@SuppressWarnings("rawtypes")
				Child child = (Child) b;
				if (child.getParent() == null) {
					System.err.println("No parent? " + child);
					continue;
				}
				if (! beans.contains(child.getParent())) {
					fail("Unknown parent for " + child + " " + child.getParent());
				}
			}
		}
	}
	
	private <T> List<T> findCommonById(
			List<T> listA, List<T> listB) {
		List<T> common = new ArrayList<T>();
		for (T a : listA) {
			int bIndex = listB.indexOf(a);
			if (bIndex < 0) {
//				System.err.println("Missing " + a);
				continue;
			}
			T b = listB.get(bIndex);
			if (a == b) {
				common.add(a);
			} else {
//				System.err.println("Non-identical equals " + a + " " + b);
			}
		}
		return common;		
	}
}

@@ -34,24 +34,59 @@
 .common;%0D%0A%0D%0A
+import static org.junit.Assert.*;%0D%0A
 import stati
@@ -119,16 +119,16 @@
 quals;%0D%0A
-
 import s
@@ -366,24 +366,73 @@
 lowBundle;%0D%0A
+import uk.org.taverna.scufl2.api.core.Workflow;%0D%0A
 import uk.or
@@ -826,16 +826,18 @@
 oid 
-megaClon
+cloneBundl
 e() 
@@ -1681,23 +1681,621 @@
 %0A%09%7D%0D%0A%0D%0A%09
-private
+@Test%0D%0A%09public void cloneWorkflow() throws Exception %7B%0D%0A%09%09Workflow original = originalWfBundle.getMainWorkflow();%0D%0A%09%09assertEquals(originalWfBundle, original.getParent());%0D%0A%09%09Workflow clone = (Workflow) original.clone();%09%09%0D%0A%09%09assertNull(clone.getParent());%0D%0A%09%09assertEquals(original.getName(), clone.getName());%0D%0A%09%09assertNotSame(original.getProcessors().getByName(%22Hello%22),%0D%0A%09%09%09%09clone.getProcessors().getByName(%22Hello%22));%0D%0A%09%09assertNotSame(original.getCurrentRevision(), clone.getCurrentRevision());%0D%0A%09%09assertEquals(original.getCurrentRevision(), clone.getCurrentRevision());%0D%0A%09%09%0D%0A%09%7D%0D%0A%09%0D%0A%09%0D%0A%09%0D%0A%09public static
  void ch
@@ -2717,22 +2717,28 @@
 %7D%0D%0A%09%0D%0A%09p
-rivate
+ublic static
  %3CT%3E Lis

test Clone workflow