/*******************************************************************************
 * 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.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.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.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.wst.common.internal.emf.resource.RendererFactory;


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 EjbEMFTest(String name, RendererFactory factory) {
    	super(name, factory);
    }
	
	public static void main(java.lang.String[] args) {
		junit.textui.TestRunner.main(new String[] { EjbEMFTest.class.getName()});
	}

	public static junit.framework.Test suite(RendererFactory factory) {
		TestSuite suite = new TestSuite(EjbEMFTest.class.getName());
		//[248158] suite.addTest(new EjbEMFTest("testEJBJarPopulation",factory));
		suite.addTest(new EjbEMFTest("test14EJBJarPopulation",factory));
		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);
	}

	/* (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;
	}
}
