/*******************************************************************************
 * Copyright (c) 2009 by SAP AG, Walldorf. 
 * 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:
 *     SAP AG - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.jaxws.dom.integration.tests.navigator;

import java.util.Iterator;

import junit.framework.TestCase;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jst.ws.jaxws.dom.integration.navigator.DOMAdapterFactoryContentProvider;
import org.eclipse.jst.ws.jaxws.dom.integration.navigator.ILoadingWsProject;
import org.eclipse.jst.ws.jaxws.dom.integration.navigator.ISEIChildList;
import org.eclipse.jst.ws.jaxws.dom.integration.navigator.IWebServiceChildList;
import org.eclipse.jst.ws.jaxws.dom.integration.navigator.ILoadingWsProject.ILoadingCanceled;
import org.eclipse.jst.ws.jaxws.dom.integration.navigator.ILoadingWsProject.ILoadingDummy;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IDOM;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IServiceEndpointInterface;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebMethod;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebParam;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebService;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWebServiceProject;
import org.eclipse.jst.ws.jaxws.dom.runtime.api.IWsDOMRuntimeExtension;
import org.eclipse.jst.ws.jaxws.dom.runtime.persistence.JaxWsWorkspaceResource;
import org.eclipse.jst.ws.jaxws.dom.ui.DomItemProviderAdapterFactory;
import org.eclipse.jst.ws.jaxws.testutils.project.TestProject;
import org.eclipse.jst.ws.jaxws.testutils.project.TestProjectsUtils;

public class DOMAdapterFactoryContentProviderTest extends TestCase 
{
	private static TestProject testPrj1; 
	
	private static IPackageFragment modelSync1;
	
	private IWebServiceProject wsProject;
	
	protected JaxWsWorkspaceResource targetResource;
	protected DOMAdapterFactoryContentProvider adapterFactory;
	
	@Override
	public void setUp() throws Exception
	{
		if(testPrj1==null)
		{
			IProject ejbProject = TestProjectsUtils.createEjb3Project("DOMCntProvTestProject1" + System.currentTimeMillis());
			testPrj1 = new TestProject(ejbProject.getProject());
			testPrj1.createSourceFolder("src");
			modelSync1 = testPrj1.createPackage("org.eclipse.test.modelsync1");
			testPrj1.createType(modelSync1, "Sei1.java", "@javax.jws.WebService(name=\"Sei1Name\") public interface Sei1{\n" +
					"@javax.jws.WebMethod(name=\"parentMethod\") public void voidMethodWithNoArgsInParent();\n" +
					"}");
			testPrj1.createType(modelSync1, "Sei2.java", "@javax.jws.WebService(name=\"Sei2Name\") public interface Sei2 extends Sei1 {\n" +
					"@javax.jws.WebMethod(name=\"voidMethodWithArgs\") public void voidMethodWithArgs(@javax.jws.WebParam(name=\"param1\") java.util.List<String> param1);\n" +
					"}");
			testPrj1.createType(modelSync1, "WS1.java", "@javax.jws.WebService(serviceName=\"WS1Name\", endpointInterface=\"org.eclipse.test.modelsync1.Sei2\") public class WS1 {}");
			testPrj1.createType(modelSync1, "WS2.java", "@javax.jws.WebService(serviceName=\"WS2Name\") public class WS2 {}");
		}
		
		targetResource = new JaxWsWorkspaceResource(JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()));
		targetResource.load(null);
		Iterator<IWebServiceProject> wsProjects = targetResource.getDOM().getWebServiceProjects().iterator();
		
		while(wsProjects.hasNext())
		{
			IWebServiceProject wsProj = wsProjects.next();
			
			if(wsProj.getName().equals(testPrj1.getProject().getName()))
			{
				this.wsProject = wsProj;
			}
		}
				
		assertNotNull(this.wsProject);
		
		adapterFactory = new DOMAdapterFactoryContentProvider() 
		{
			@Override
			protected IWebServiceProject getWsProject(final IDOM dom, final IProject project) {
				return wsProject;
			}
		};
		
		targetResource.startSynchronizing();
	}
	
	@Override
	public void tearDown() throws CoreException
	{
		targetResource.stopSynchronizing();
	}
	
	public void testDOMAdapterFactoryContentProvider() 
	{
		assertNotNull(adapterFactory.getAdapterFactory());
		assertTrue(adapterFactory.getAdapterFactory() instanceof DomItemProviderAdapterFactory);
	}

	public void testDOMAdapterFactoryContentProviderAdapterFactory() 
	{
		adapterFactory = new DOMAdapterFactoryContentProvider(new DomItemProviderAdapterFactory());
		
		assertNotNull(adapterFactory.getAdapterFactory());
		assertTrue(adapterFactory.getAdapterFactory() instanceof DomItemProviderAdapterFactory);
	}

	public void testGetChildrenListsObject() 
	{
		Object[] children = adapterFactory.getChildren(testPrj1.getProject());
		
		assertNotNull(children);
		assertEquals(children.length, 1);
		assertTrue(children[0] instanceof IWebServiceProject);
		
		children = adapterFactory.getChildren(children[0]);
		
		assertNotNull(children);
		assertEquals(children.length, 2);
		assertTrue(children[0] instanceof ISEIChildList);
		assertTrue(children[1] instanceof IWebServiceChildList);
		
		Object[] sEIs = adapterFactory.getChildren(children[0]);
		
		assertNotNull(sEIs);
		assertEquals(3, sEIs.length);
		assertTrue(sEIs[0] instanceof IServiceEndpointInterface);
		assertTrue(sEIs[1] instanceof IServiceEndpointInterface);
		assertTrue(sEIs[2] instanceof IServiceEndpointInterface);
		
		Object[] wSs = adapterFactory.getChildren(children[1]);
		
		assertNotNull(wSs);
		assertEquals(wSs.length, 2);
		assertTrue(wSs[0] instanceof IWebService);
		assertTrue(wSs[1] instanceof IWebService);
	}
	
	public void testHasChildrenObject() 
	{
		// IWebServiceProject
		Object[] children = adapterFactory.getChildren(testPrj1.getProject());
		
		assertTrue(adapterFactory.hasChildren(children[0]));
		
		// ISEIChildList & IWebServiceChildList
		children = adapterFactory.getChildren(children[0]);
		
		assertTrue(adapterFactory.hasChildren(children[0]));
		assertTrue(adapterFactory.hasChildren(children[1]));
		
		// null parameter
		assertFalse(adapterFactory.hasChildren(null));
	}
	
	public void testChildrenIWebService()
	{
		IWebService ws = findWs("org.eclipse.test.modelsync1.WS1");
		assertNotNull(ws);
		assertTrue(adapterFactory.hasChildren(ws));
		assertEquals(1, adapterFactory.getChildren(ws).length);
		assertTrue(adapterFactory.getChildren(ws)[0] instanceof IServiceEndpointInterface);
		
		// check if adapted only once
		DOMAdapterFactoryContentProvider otherFactory = new DOMAdapterFactoryContentProvider();
		otherFactory.getChildren(ws);
		assertEquals(2, ws.eAdapters().size());
	}
	
	public void testChildrenIServiceEndpointInterface()
	{
		IServiceEndpointInterface sei = findSei("org.eclipse.test.modelsync1.Sei2");
		assertNotNull(sei);
		assertTrue(adapterFactory.hasChildren(sei));
		assertEquals(2, adapterFactory.getChildren(sei).length);
		assertTrue(adapterFactory.getChildren(sei)[0] instanceof IWebMethod);
		DOMAdapterFactoryContentProvider otherFactory = new DOMAdapterFactoryContentProvider();
		otherFactory.getChildren(sei);
		assertEquals(2, sei.eAdapters().size());
		
		IWebService ws = findWs("org.eclipse.test.modelsync1.WS2");
		assertNotNull(ws);
		assertFalse(adapterFactory.hasChildren(ws.getServiceEndpoint()));
		assertEquals(0, adapterFactory.getChildren(ws.getServiceEndpoint()).length);
		// check if adapted only once
		otherFactory.getChildren(ws.getServiceEndpoint());
		assertEquals(2, ws.getServiceEndpoint().eAdapters().size());
	}
	
	public void testChildrenWebMethod()
	{
		IServiceEndpointInterface sei = findSei("org.eclipse.test.modelsync1.Sei2");
		assertNotNull(sei);
		
		IWebMethod method = findMethod(sei, "voidMethodWithArgs");
		assertNotNull(method);	
		assertTrue(adapterFactory.hasChildren(method));
		assertEquals(1, adapterFactory.getChildren(method).length);
		assertTrue(adapterFactory.getChildren(method)[0] instanceof IWebParam);
		
		 method = findMethod(sei, "voidMethodWithNoArgsInParent");
		assertNotNull(method);
		assertFalse(adapterFactory.hasChildren(method));
		assertEquals(0, adapterFactory.getChildren(method).length);		
	}
	
	public void testChildrenWebParam()
	{
		IServiceEndpointInterface sei = findSei("org.eclipse.test.modelsync1.Sei2");
		assertNotNull(sei);
		
		IWebMethod method = findMethod(sei, "voidMethodWithArgs");
		assertNotNull(method);
		assertFalse(adapterFactory.hasChildren(method.getParameters().get(0)));
		assertEquals(0, adapterFactory.getChildren(method.getParameters().get(0)).length);
	}
	
	
	private IServiceEndpointInterface findSei(final String implName)
	{
		for(IServiceEndpointInterface sei : wsProject.getServiceEndpointInterfaces()) 
		{
			if(sei.getImplementation().equals(implName)) {
				return sei;
			}
		}
		
		return null;
	}	
	
	private IWebService findWs(final String implName)
	{
		for(IWebService ws : wsProject.getWebServices()) 
		{
			if(ws.getImplementation().equals(implName)) {
				return ws;
			}
		}
		
		return null;
	}	
	
	private IWebMethod findMethod(IServiceEndpointInterface sei, final String methodName) 
	{
		for(IWebMethod method : sei.getWebMethods()) 
		{
			if(method.getName().equals(methodName)) {
				return method;
			}
		}
		
		return null;
	}
	
//	public void testNotifyChanged()
//	{
//		Object[] children = adapterFactory.getChildren(testPrj1.getProject());
//		
//		try
//		{
//			testPrj1.createType(modelSync1, "Sei3.java", "@javax.jws.WebService(name=\"Sei3Name\") public interface Sei3 {}");
//			testPrj1.createType(modelSync1, "WS3.java", "@javax.jws.WebService(serviceName=\"WS3Name\", endpointInterface=\"org.eclipse.test.modelsync1.Sei3\") public class WS3 {}");
//		}
//		catch(JavaModelException e)
//		{
//			fail(e.toString());
//		}
//		
//		children = adapterFactory.getChildren(children[0]);
//		
//		Object[] sEIs = adapterFactory.getChildren(children[0]);
//		
//		assertEquals(sEIs.length, 3);
//		
//		Object[] wSs = adapterFactory.getChildren(children[1]);
//		
//		assertEquals(wSs.length, 3);
//	}
	
	public void testGetWSProject()
	{
		adapterFactory = new DOMAdapterFactoryContentProvider();
		
		Object[] children = adapterFactory.getChildren(testPrj1.getProject());
		assertNotNull(children);
	}
	
	public void testGetWsProjectDomNotLoaded()
	{
		adapterFactory = new DOMAdapterFactoryContentProvider() {
			@Override
			protected IWebServiceProject getWsProject(final IDOM dom, final IProject project) {
				return null;
			}
		};
		Object[] children = adapterFactory.getChildren(testPrj1.getProject());
		assertEquals(1, children.length);
		assertTrue(children[0] instanceof ILoadingWsProject);
		children = adapterFactory.getChildren(children[0]);
		assertEquals(1, children.length);
		assertTrue(children[0] instanceof ILoadingDummy);
	}
	
	public void testGetWsProjectChildsDomLoadNotCanceled()
	{
		ILoadingWsProject loadingProject = new ILoadingWsProject() {
			public IProject getProject() { return null; }
			public boolean isLoadCanceled() {return false;}
		};
			
		Object[] children = adapterFactory.getChildren(loadingProject);
		assertEquals(1, children.length);
		assertTrue(children[0] instanceof ILoadingDummy);		
	}
	
	public void testGetWsProjectChildsDomLoadCanceled()
	{
		ILoadingWsProject loadingProject = new ILoadingWsProject() {
			public IProject getProject() { return null; }
			public boolean isLoadCanceled() {return true;}
		};
			
		Object[] children = adapterFactory.getChildren(loadingProject);
		assertEquals(1, children.length);
		assertTrue(children[0] instanceof ILoadingCanceled);		
	}
	
	public void testGetSupportingRuntime()
	{
		DOMAdapterFactoryContentProviderMy provider = new DOMAdapterFactoryContentProviderMy();
		IWsDOMRuntimeExtension runtime = provider.getSupportingRuntime(testPrj1.getProject());
		assertNotNull(runtime);
	}
	
	protected class DOMAdapterFactoryContentProviderMy extends DOMAdapterFactoryContentProvider
	{
		@Override
		public IWsDOMRuntimeExtension getSupportingRuntime(final IProject project) {
			return super.getSupportingRuntime(project);
		}
	};
}
