/*******************************************************************************
 * Copyright (c) 2003, 2006 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.internal.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jem.internal.adapters.jdom.JavaJDOMAdapterFactory;
import org.eclipse.jem.internal.java.adapters.ReadAdaptor;
import org.eclipse.jem.internal.java.adapters.ReflectionAdaptor;
import org.eclipse.jem.java.Field;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.JavaVisibilityKind;
import org.eclipse.jem.java.util.NotificationUtil;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jem.util.emf.workbench.nature.EMFNature;
import org.eclipse.jst.j2ee.ejb.CMPAttribute;
import org.eclipse.jst.j2ee.ejb.ContainerManagedEntity;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.ejb.EjbPackage;
import org.eclipse.jst.j2ee.ejb.internal.impl.EjbFactoryImpl;

/**
 * This adapter is used to listen for changes to the ejb class or the primary key class in order to
 * reflect the proper CMP field types and the proper key attributes.
 */
public class CMPJavaChangeSynchronizationAdapter extends AdapterImpl {

	private static final String J2EE_PROJ_MIGRATION_ADAPTER = "J2EEProjectMigration"; //$NON-NLS-1$

	protected static EjbPackage EJB_PACK = EjbFactoryImpl.getPackage();

	private static HashMap enablementMap = new HashMap();

	public static void disable(ContainerManagedEntity cmp) {
		enablementMap.put(cmp, Boolean.FALSE);
	}

	public static void enable(ContainerManagedEntity cmp) {
		enablementMap.put(cmp, Boolean.TRUE);
	}

	public static boolean isEnabled(ContainerManagedEntity cmp) {
		if (!enablementMap.containsKey(cmp))
			return true;
		return ((Boolean) enablementMap.get(cmp)).booleanValue();
	}

	protected Resource cmpResource;

	private List foundKeys = new ArrayList();
	
	/*
	 * This Set is used to avoid reacting to notifications for a notifier while
	 * updating that notifier.
	 */
	private Set updatingSet = new HashSet();

	public CMPJavaChangeSynchronizationAdapter() {
		super();
	} // EJBKeyShapeMaintenanceAdapter

	/**
	 * Notifies if there is change in the key shape.
	 * 
	 * @param Notification
	 *            msg - Message indicates what has changed.
	 */
	@Override
	public void notifyChanged(Notification msg) {
		if (!isEnabled(getCMP())) {
			enable(getCMP());
			return;
		}
		Object notifier = msg.getNotifier();
		if (!updatingSet.contains(notifier)) {
			try {
				updatingSet.add(notifier);
				switch (msg.getEventType()) {
					case Notification.SET :
						setNotification(msg);
						break;
					case Notification.UNSET :
						unsetNotification(msg);
						break;
					case Notification.REMOVING_ADAPTER :
						removeAdapterNotification(msg);
						break;
					case ReflectionAdaptor.EVENT :
						jemFlushNotification(msg);
						break;
				}
			} finally {
				updatingSet.remove(notifier);
			}
		}
	}

	/**
	 * Use if the there was an set notification.
	 * 
	 * @param Notification
	 *            msg - Message indicates what has changed.
	 */
	protected void setNotification(Notification msg) {
		EStructuralFeature sf = (EStructuralFeature) msg.getFeature();
		if (sf == EJB_PACK.getEnterpriseBean_EjbClass() || sf == EJB_PACK.getEntity_PrimaryKey()) {
			if (!isMigrating()) {
				removeAttributeMaintenanceAdapter((Notifier) msg.getOldValue());
				addAttributeMaintenanceAdapter((Notifier) msg.getNewValue());
				touchKeyShapeAdapter(msg);
			}
		} else if (sf == EJB_PACK.getEntity_PrimaryKey()) {
			removeAttributeMaintenanceAdapter((Notifier) msg.getOldValue());
			if (shouldAddToPrimaryKeyClass((ContainerManagedEntity) getTarget()))
				addAttributeMaintenanceAdapter((Notifier) msg.getNewValue());
		} else {
			jemFlushNotification(msg); //In EMF a TOUCH is a SET.
		}
	} // setNotification

	/**
	 * @return
	 */
	private boolean isMigrating() {
		EJBJar jar = ((ContainerManagedEntity) getTarget()).getEjbJar();
		if (jar != null)
			return EcoreUtil.getExistingAdapter(jar, J2EE_PROJ_MIGRATION_ADAPTER) != null;
		return false;
	}

	// setNotification
	/**
	 * Use if the there was an unset notification.
	 * 
	 * @param Notification
	 *            msg - Message indicates what has changed.
	 */
	protected void unsetNotification(Notification msg) {
		EStructuralFeature sf = (EStructuralFeature) msg.getFeature();
		if ((sf == EJB_PACK.getEnterpriseBean_EjbClass() || sf == EJB_PACK.getEntity_PrimaryKey()) && !isMigrating()) {
			removeAttributeMaintenanceAdapter((Notifier) msg.getOldValue());
		}
	} // unsetNotification

	/**
	 * Use if the there was an touch notification.
	 * 
	 * @param Notification
	 *            msg - Message indicates what has changed.
	 */
	protected void jemFlushNotification(Notification msg) {
		if ((NotificationUtil.isFlushNewEvent(msg) || NotificationUtil.isFlushEvent(msg)) && !isMigrating()) {
			if (msg.getNotifier() == ((ContainerManagedEntity) getTarget()).getEjbClass()) {
				touchBeanAdapter(msg);
			} else if (msg.getNotifier() == ((ContainerManagedEntity) getTarget()).getPrimaryKey()) {
				touchKeyShapeAdapter(msg);
			} // if
			//if the notifier is eq the primary key
			//else ejb bean class flush
		} // if
	} // touchNotification

	protected void removeAdapterNotification(Notification msg) {
		if (msg.getOldValue() == this && msg.getNotifier() instanceof ContainerManagedEntity) {
			ContainerManagedEntity cmp = (ContainerManagedEntity) msg.getNotifier();
			if (cmp.getEjbClass() != null)
				cmp.getEjbClass().eAdapters().remove(this);
			if (cmp.getPrimaryKey() != null)
				cmp.getPrimaryKey().eAdapters().remove(this);
		}
	}

	/**
	 * Adds the key shape adapter
	 * 
	 * @param Notifier
	 *            notifier - The current notifier.
	 */
	protected void addAttributeMaintenanceAdapter(Notifier notifier) {
		if (notifier != null && !notifier.eAdapters().contains(this))
			notifier.eAdapters().add(this);
	}

	/**
	 * Remove the key shape adapter
	 */
	protected void removeAttributeMaintenanceAdapter(Notifier notifier) {
		if (notifier != null)
			notifier.eAdapters().remove(this);
	}

	/**
	 * The key has been touched.
	 * 
	 * @param Notification
	 *            msg - The notification message.
	 */
	protected void touchKeyShapeAdapter(Notification msg) {
		if (msg == null)
			return;
		ContainerManagedEntity cmp = (ContainerManagedEntity) getTarget();
		JavaClass primaryKeyClass = cmp.getPrimaryKey();
		//Synch the two lists.
		synchCMPandKeyAttributes(cmp, primaryKeyClass);
	} // touchKeyShapeAdapter

	/**
	 * The ejb class has been flushed.
	 * 
	 * @param Notification
	 *            msg - The notification message.
	 */
	protected void touchBeanAdapter(Notification msg) {
		if (msg == null)
			return;
		ContainerManagedEntity cmp = (ContainerManagedEntity) getTarget();
		List cmpAttributes = cmp.getPersistentAttributes();
		if (cmpAttributes != null && !cmpAttributes.isEmpty()) {
			boolean modFlag = getCurrentModificationFlag();
			try {
				for (int i = 0; i < cmpAttributes.size(); i++) {
					CMPAttribute cmpAttr = (CMPAttribute) cmpAttributes.get(i);
					if (cmpAttr != null && !cmpAttr.isDerived()) {
						cmpAttr.setEType(null);
					}
				}
			} finally {
				setModificationFlag(modFlag);
			}
		}
		synchCMPandKeyAttributes(cmp, cmp.getPrimaryKey());
	}

	/**
	 * Synchronzies the cmp and primary key class attributes.
	 * 
	 * @param ContainerManagedEntity
	 *            cmp - The cmp.
	 * @param JavaClass
	 *            primaryKeyClass
	 */
	protected void synchCMPandKeyAttributes(ContainerManagedEntity cmp, JavaClass primaryKeyClass) {
		if (cmp == null || primaryKeyClass == null || cmp.getPrimKeyField() != null || primaryKeyClass.getQualifiedName().startsWith("java.lang")) //$NON-NLS-1$
			return;

		// make sure we flush the primary key to get latest updates if no save
		// took place
		flushPrimaryKeyClass(primaryKeyClass);

		List cmpAttributes = cmp.getPersistentAttributes();
		if (cmpAttributes != null) {
			foundKeys.clear();
			List keyAttributesList = cmp.getKeyAttributes();
			foundKeys.addAll(keyAttributesList);
			boolean modFlag = getCurrentModificationFlag();
			try {
				List keyFields = primaryKeyClass.getFieldsExtended();
				for (int i = 0; i < keyFields.size(); i++) {
					Field field = (Field) keyFields.get(i);
					if (field.getJavaVisibility() != JavaVisibilityKind.PUBLIC_LITERAL)
						continue;
					String fieldName = field.getName();
					if (fieldName != null) {
						CMPAttribute keyAttr = cmp.getKeyAttribute(fieldName);
						if (keyAttr == null)
							cmp.addKeyAttributeName(fieldName);
						else
							foundKeys.remove(keyAttr);
					}
				}
				if (!foundKeys.isEmpty())
					keyAttributesList.removeAll(foundKeys);
			} finally {
				setModificationFlag(modFlag);
			}
		}
	}

	@Override
	public void setTarget(Notifier newTarget) {
		boolean isChanged = getTarget() != newTarget;
		if (newTarget == null) {
			super.setTarget(newTarget);
			cmpResource = null;
		} else if (newTarget instanceof ContainerManagedEntity) {
			Resource res = ((ContainerManagedEntity) newTarget).eResource();
			if (res != null && res.getResourceSet() != null) {
				super.setTarget(newTarget);
				if (isChanged)
					initializeTarget();
			}
		}
	}

	/**
	 *  
	 */
	private void initializeTarget() {
		ContainerManagedEntity cmp = (ContainerManagedEntity) getTarget();
		addAttributeMaintenanceAdapter(cmp.getEjbClass());
		if (shouldAddToPrimaryKeyClass(cmp))
			addAttributeMaintenanceAdapter(cmp.getPrimaryKey());
	}

	private boolean shouldAddToPrimaryKeyClass(ContainerManagedEntity cmp) {
		return cmp.getPrimKeyField() == null && cmp.getPrimaryKey() != null && !cmp.getPrimaryKey().getQualifiedName().startsWith("java.lang"); //$NON-NLS-1$
	}

	protected Resource getCMPResource() {
		if (cmpResource == null && getTarget() != null)
			cmpResource = ((EObject) getTarget()).eResource();
		return cmpResource;
	}

	protected boolean getCurrentModificationFlag() {
		return getCMPResource() != null && cmpResource.getContents() != null ? cmpResource.isModified() : false;
	}

	protected void setModificationFlag(boolean aBoolean) {
		if (getCMPResource() != null)
			getCMPResource().setModified(aBoolean);
	}

	public ContainerManagedEntity getCMP() {
		if (getTarget() instanceof ContainerManagedEntity)
			return (ContainerManagedEntity) getTarget();
		return null;
	}

	protected boolean flushPrimaryKeyClass(JavaClass primaryKeyClass) {
		// ensure the primary key class is flushed and reloaded to get latest
		// content
		IProject p = ProjectUtilities.getProject(primaryKeyClass);
		try {
			List natures = EMFNature.getRegisteredRuntimes(p);
			EMFNature nature = null;
			for (int i = 0; i < natures.size(); i++) {
				if (natures.get(i) instanceof EMFNature)
					nature = (EMFNature) natures.get(i);
			}
			if(nature !=null ){
				List adapterFactories = nature.getResourceSet().getAdapterFactories();
				AdapterFactory factory = EcoreUtil.getAdapterFactory(adapterFactories, ReadAdaptor.TYPE_KEY);
				if (factory instanceof JavaJDOMAdapterFactory) {
					JavaJDOMAdapterFactory javaFactory = (JavaJDOMAdapterFactory) factory;
					javaFactory.flushReflectionNoNotification(primaryKeyClass.getQualifiedName());
					return true;
				}
			}
		} catch (Exception e) {
			// We don't really care what the exception was, we'll just bail out
			// and return false;
		}
		return false;
	}
}
