/*******************************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.archive.emftests;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import junit.framework.TestSuite;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.jem.java.internal.impl.JavaClassImpl;
import org.eclipse.jst.j2ee.application.ApplicationFactory;
import org.eclipse.jst.j2ee.application.ApplicationPackage;
import org.eclipse.jst.j2ee.archive.testutilities.EMFAttributeFeatureGenerator;
import org.eclipse.jst.j2ee.common.CommonFactory;
import org.eclipse.jst.j2ee.common.SecurityIdentity;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchiveFactory;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchivePackage;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EJBJarFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.DuplicateObjectException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.core.tests.bvt.AutomatedBVT;
import org.eclipse.jst.j2ee.ejb.CMPAttribute;
import org.eclipse.jst.j2ee.ejb.CMRField;
import org.eclipse.jst.j2ee.ejb.EJBResource;
import org.eclipse.jst.j2ee.ejb.EjbFactory;
import org.eclipse.jst.j2ee.ejb.EjbPackage;
import org.eclipse.jst.j2ee.ejb.MethodPermission;
import org.eclipse.jst.j2ee.ejb.RoleSource;
import org.eclipse.jst.j2ee.ejb.internal.impl.EJBRelationshipRoleImpl;
import org.eclipse.jst.j2ee.ejb.internal.impl.MethodPermissionImpl;
import org.eclipse.jst.j2ee.ejb.internal.impl.QueryMethodImpl;
import org.eclipse.jst.j2ee.internal.J2EEInit;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.webapplication.WebapplicationFactory;
import org.eclipse.jst.j2ee.webapplication.WebapplicationPackage;


public class EjbEMFTest extends GeneralEMFPopulationTest {
	static {
		//Temporary workaround to keep packages from being registered twice
		J2EEInit.init();
	}
	protected static final EjbPackage EJB_PKG = EjbPackage.eINSTANCE;
	EARFile earFile;
	protected EJBJarFile ejbFile;
	EObject mesBean, entityBean;
	SecurityIdentity secID;
	RoleSource roleSource;
	int NUM_BEANS = 10;
	final int NUM_RELATION_ROLES = 2;
	int createdBeans = 0;
	int createdSecRoles = 0;
	protected int createdSecurityIdentities = 0;
	boolean mpFlag = false;
	boolean firstReturnTypeMapping = true;
	public EjbEMFTest(String name) {
		super(name);
	}

	public CommonarchiveFactory getArchiveFactory() {
		return CommonarchivePackage.eINSTANCE.getCommonarchiveFactory();
	}

	public EjbFactory getEjbFactory() {
		return EJB_PKG.getEjbFactory();
	}

	public ApplicationFactory getApplicationFactory() {
		return ApplicationPackage.eINSTANCE.getApplicationFactory();
	}

	public WebapplicationFactory getWebAppFactory() {
		return WebapplicationPackage.eINSTANCE.getWebapplicationFactory();
	}

	public static void main(java.lang.String[] args) {
		junit.textui.TestRunner.main(new String[] { EjbEMFTest.class.getName()});
	}
	public static junit.framework.Test suite() {
		TestSuite suite = new TestSuite();

		/*System.out.println("Switching to SAX Renderer in " + EjbEMFTest.class.getName());
		suite.addTest(new AllSAXTests("testSwitchRenderer"));*/
		suite.addTest(new EjbEMFTest("testEJBJarPopulation"));
/* xsd problem - see bugzilla 152355
		suite.addTest(new EjbEMFTest("test14EJBJarPopulation"));
*/
		return suite;
	}

	public void testEJBJarPopulation() throws Exception {
		EMFAttributeFeatureGenerator.reset();
		createEAR();
		createEJB();

		EJBResource DD = (EJBResource) ejbFile.getDeploymentDescriptorResource();
		//TODO: individual test for each version
		DD.setVersionID(J2EEVersionConstants.J2EE_1_3_ID);
		setVersion(VERSION_1_3);
		setModuleType(EJB);
		populateRoot(DD.getRootObject());

		String out = AutomatedBVT.baseDirectory +"testOutput/TestEJBEAR";
		earFile.extractTo(out, Archive.EXPAND_ALL);
		earFile.close();
		setEquivalentLines(getEquivalentLinesMap());
		//Compare work in progress
		String curDir = AutomatedBVT.baseDirectory;
		String exampleDeploymentDesURI = curDir + "/EMFTestNoID/ejb-jar.xml";
		String curDeploymentDesURI = curDir + "testOutput/TestEJBEAR/fooEJB/META-INF/ejb-jar.xml";
		setIgnoreAtt(ignorableAttributes());
		compareContentsIgnoreWhitespace(curDeploymentDesURI, exampleDeploymentDesURI, null);
//		DD.unload();
//		DD.load(new HashMap());
	}
	
	public void test14EJBJarPopulation() throws Exception {
		EMFAttributeFeatureGenerator.reset();
		createEAR();
		createEJB();

		EJBResource DD = (EJBResource) ejbFile.getDeploymentDescriptorResource();
		//TODO: individual test for each version
		DD.setVersionID(J2EEVersionConstants.J2EE_1_4_ID);
		setVersion(VERSION_1_4);
		setModuleType(EJB);
		//setGeneralDepth(2);
		populateRoot(DD.getRootObject());
		String out = AutomatedBVT.baseDirectory +"testOutput/TestEJBEAR14";
		earFile.extractTo(out, Archive.EXPAND_ALL);
		earFile.close();
		
		setEquivalentLines(getEquivalentLinesMap());
		getEJB();
		assertEquals("2.1", ejbFile.getDeploymentDescriptor().getVersion());
		out = AutomatedBVT.baseDirectory +"testOutput/TestEJBEAR14_2";
		ejbFile.extractTo(out, Archive.EXPAND_ALL);
		ejbFile.close();

		//Compare work in progress
		String curDir = AutomatedBVT.baseDirectory;
		String exampleDeploymentDesURI = out + "/META-INF/ejb-jar.xml";
		String curDeploymentDesURI = curDir + "testOutput/TestEJBEAR14/fooEJB/META-INF/ejb-jar.xml";
		setIgnoreAtt(ignorableAttributes());
		compareContentsIgnoreWhitespace(curDeploymentDesURI, exampleDeploymentDesURI, null);
	}
	
	/**
	 * @return
	 */
	private Map getEquivalentLinesMap() {
		Map lines = new HashMap();
		lines.put("<cascade-delete></cascade-delete>", "<cascade-delete/>");
		lines.put("<method-params></method-params>","<method-params/>");
		lines.put("<unchecked></unchecked>","<unchecked/>"); 
		lines.put("<use-caller-identity></use-caller-identity>","<use-caller-identity/>");
		return lines;
	}

	public void getEJB() throws DuplicateObjectException, OpenFailureException {
		String in = AutomatedBVT.baseDirectory +"testOutput/TestEJBEAR14/fooEJB";
		ejbFile = getArchiveFactory().openEJBJarFile(in);
		assertTrue(ejbFile.getDeploymentDescriptor() != null);
	}

	public void createEJB() throws DuplicateObjectException {
		ejbFile = getArchiveFactory().createEJBJarFileInitialized("fooEJB");
		ejbFile = (EJBJarFile) earFile.addCopy(ejbFile);
		ejbFile.getDeploymentDescriptor().setDisplayName("fooEJB");
		assertTrue(ejbFile.getDeploymentDescriptor() != null);
	}

	public void createEAR() {
		String earName = "Test.ear";
		earFile = getArchiveFactory().createEARFileInitialized(earName);
		assertTrue(earFile.getDeploymentDescriptor() != null);
	}

	public EObject createInstance(EReference ref, EObject eObject) {
		EClass eClassifier = (EClass)ref.getEType();
		if (eClassifier.getName().equals("EnterpriseBean")) {
			createdBeans++;
			switch (createdBeans) {
				case (3) :
					return createContainerManagedEntityInstance(eClassifier);
				case (7) :
					return createMessageBeanInstance(eClassifier);
				case (4) :
				case (8) :
					return createSessionBeanInstance(eClassifier);
				default :
					return createEntityBeanInstance(eClassifier);
			}
		} else if (eClassifier.getName().equals("SecurityIdentity"))
			return createSecurityIdentitiyInstance(eClassifier);
		else if (eClassifier.getName().equals("RoleSource"))
			return createRoleSourceInstance(eClassifier);
		else if (eClassifier == EcorePackage.eINSTANCE.getEAttribute())
			return getEjbFactory().createCMPAttribute();
		return super.createInstance(ref,eObject);
	}

	private EObject createSecurityIdentitiyInstance(EClass eClassifier) {
		/* Alternate types */
		createdSecRoles++;
		if ((createdSecRoles & 1) == 0)
			return CommonFactory.eINSTANCE.createUseCallerIdentity();
		else
			return CommonFactory.eINSTANCE.createRunAsSpecifiedIdentity();
	}

	private EObject createRoleSourceInstance(EClass eClassifier) {
		return ((EjbFactory) eClassifier.getEPackage().getEFactoryInstance()).createRoleSource();
	}

	private EObject createMessageBeanInstance(EClass eClassifier) {
		return ((EjbFactory) eClassifier.getEPackage().getEFactoryInstance()).createMessageDriven();
	}

	private EObject createSessionBeanInstance(EClass eClassifier) {
		return ((EjbFactory) eClassifier.getEPackage().getEFactoryInstance()).createSession();
	}

	private EObject createEntityBeanInstance(EClass eClassifier) {
		return ((EjbFactory) eClassifier.getEPackage().getEFactoryInstance()).createEntity();
	}

	private EObject createContainerManagedEntityInstance(EClass eClassifier) {
		return EjbFactory.eINSTANCE.createContainerManagedEntity();
	}

	/**
	 * @see org.eclipse.jst.j2ee.archive.test.GeneralEMFTest#getDepthForAttribute(EReference)
	 */
	public int getDepthForAttribute(EStructuralFeature ref) {
		if (ref.getName().equals("enterpriseBeans"))
			return NUM_BEANS;
		else if (ref.getName().equals("entityBeans"))
			return NUM_BEANS;
		else if (ref.getName().equals("relationshipRoles"))
			return NUM_RELATION_ROLES;
		return super.getDepthForAttribute(ref);
	}

	/* (non-Javadoc)
	* @see com.ibm.etools.archive.emftest.GeneralEMFPopulationTest#populateFeatures(org.eclipse.emf.ecore.EObject)
	*/
	public void populateFeatures(EObject eObject) {
		if (eObject.eClass() == EJB_PKG.getCMPAttribute()) {
			((CMPAttribute) eObject).setName((String) EMFAttributeFeatureGenerator.createAttribute(EcorePackage.eINSTANCE.getENamedElement_Name(),eObject));
			((CMPAttribute) eObject).setEType((EClassifier) EMFAttributeFeatureGenerator.createJavaClassProxy(EcorePackage.eINSTANCE.getETypedElement_EType(),eObject));
		} else if (eObject.eClass() == EJB_PKG.getCMRField()) {
			((CMRField) eObject).setName((String) EMFAttributeFeatureGenerator.createAttribute(EcorePackage.eINSTANCE.getENamedElement_Name(),eObject));
			populateSharedReference(eObject, EJB_PKG.getCMRField_CollectionType());
			populateSharedReference(eObject, EJB_PKG.getCMRField_Role());		
		} else
			super.populateFeatures(eObject);
	}

	/* (non-Javadoc)
	 * @see com.ibm.etools.archive.emftest.GeneralEMFPopulationTest#populateAttributes(org.eclipse.emf.ecore.EObject)
	 */
	protected void populateAttributes(EObject eObject) {
		if (eObject instanceof QueryMethodImpl) {
			List attributes = eObject.eClass().getEAllAttributes();
			for (int i = 0; i < attributes.size(); i++) { 
				EAttribute att = (EAttribute) attributes.get(i);
				if (att.equals(EJB_PKG.getMethodElement_Description()) || att.equals(EJB_PKG.getMethodElement_EnterpriseBean()) || att.equals(EJB_PKG.getMethodElement_Type()) )
					continue;
				Object value = createAttributeValue(att, eObject);
				if (att.getName().equals("parms") && value == null){
					value = createAttributeValue(att, eObject);
				}
				if (att.isChangeable())
					eObject.eSet(att, value);
			}
		} else if (eObject instanceof MethodPermissionImpl) {
			List attributes = eObject.eClass().getEAllAttributes();
			for (int i = 0; i < attributes.size(); i++) {
				EAttribute att = (EAttribute) attributes.get(i);
				if(att.getName().equals("unchecked") && mpFlag){
					continue;					
				}	
				
				Object value = createAttributeValue(att, eObject);
				if (att.isChangeable())
					eObject.eSet(att, value);
			} 
			mpFlag = !mpFlag;
		} else if (eObject instanceof EJBRelationshipRoleImpl) {
			List attributes = eObject.eClass().getEAllAttributes();
			EAttribute lastAttr = null;
			Object value = null;
			for (int i = 0; i < attributes.size(); i++) {
				EAttribute att = (EAttribute) attributes.get(i);
				if (att.getName().equals("cascadeDelete") && (lastAttr.getName().equals("multiplicity") && !value.toString().equals("Many")))
					continue;

				value = createAttributeValue(att, eObject);
				if (att.isChangeable())
					eObject.eSet(att, value);
				lastAttr = att;
		}
			mpFlag = !mpFlag;
		} else
			super.populateAttributes(eObject);
	}
	

	protected void populateSharedReference(EObject eObject, EReference ref) {
		if (ref == EJB_PKG.getCMRField_CollectionType()) {
			setReferenceValue(eObject, ref, JavaClassImpl.createClassRef("java.util.Collection"));
			return;
		} else if(eObject instanceof MethodPermission && ref.getName().equals("roles")){
			//if method permission unchecked ignore roles
			if(mpFlag){
				return;
			}
			mpFlag = !mpFlag;
		}
		super.populateSharedReference(eObject, ref);
	}

	public HashSet ignorableAttributes(){
		HashSet set = new HashSet();
		set.add("id");
		return set;
	}

	/* (non-Javadoc)
	 * @see com.ibm.etools.archive.emftest.GeneralEMFPopulationTest#createAttributeValue(org.eclipse.emf.ecore.EAttribute, org.eclipse.emf.ecore.EObject)
	 */
	protected Object createAttributeValue(EAttribute att, EObject eObject) {
		//eat the first return type mapping because the order was changed.
		if (firstReturnTypeMapping && att.equals(EJB_PKG.getQuery_ReturnTypeMapping())){
			super.createAttributeValue(att,eObject);
			firstReturnTypeMapping = false;
		} else if (att.equals(EJB_PKG.getEnterpriseBean_Name()))
			return EMFAttributeFeatureGenerator.createAttribute(att,EJB_PKG.getEntity());
		return super.createAttributeValue(att, eObject);
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
		super.tearDown();
		earFile = null;
		ejbFile = null;
		mesBean = null;
		entityBean = null;
		secID = null;
		roleSource = null;

		
}
}
