/*******************************************************************************
 * <copyright>
 *
 * Copyright (c) 2005, 2011 SAP AG.
 * 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:
 *    Stefan Dimov - initial API, implementation and documentation
 *
 * </copyright>
 *
 *******************************************************************************/
package org.eclipse.jpt.jpadiagrameditor.ui.internal.feature;

import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.IContext;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.context.IRemoveContext;
import org.eclipse.graphiti.features.context.impl.AddContext;
import org.eclipse.graphiti.features.context.impl.RemoveContext;
import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
import org.eclipse.graphiti.mm.algorithms.RoundedRectangle;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jpt.common.core.JptResourceModel;
import org.eclipse.jpt.common.core.resource.java.Annotation;
import org.eclipse.jpt.common.core.resource.java.JavaResourceAbstractType;
import org.eclipse.jpt.common.core.resource.java.JavaResourceCompilationUnit;
import org.eclipse.jpt.common.utility.model.event.CollectionAddEvent;
import org.eclipse.jpt.common.utility.model.event.CollectionChangeEvent;
import org.eclipse.jpt.common.utility.model.event.CollectionClearEvent;
import org.eclipse.jpt.common.utility.model.event.CollectionRemoveEvent;
import org.eclipse.jpt.common.utility.model.listener.CollectionChangeListener;
import org.eclipse.jpt.jpa.core.JpaFile;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.JptJpaCorePlugin;
import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMapping;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpa.core.resource.java.OwnableRelationshipMappingAnnotation;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.JPADiagramEditorPlugin;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.AddEntityContext;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.provider.IJPAEditorFeatureProvider;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPAEditorConstants;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPAEditorUtil;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JPASolver;
import org.eclipse.jpt.jpadiagrameditor.ui.internal.util.JpaArtifactFactory;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;


public abstract class RefactorEntityFeature extends AbstractCustomFeature {

	protected JavaPersistentType jpt = null;
	protected Set<JavaPersistentAttribute> ats = null;
	protected boolean hasNameAnnotation = false;

	public RefactorEntityFeature(IFeatureProvider fp) {
		super(fp);
	}
	
	@Override
	public boolean isAvailable(IContext context) {
    	if (!(context instanceof ICustomContext))
    		return false;
    	ICustomContext ctx = (ICustomContext)context;
    	PictogramElement pe = ctx.getInnerPictogramElement();
    	Object bo = getFeatureProvider().getBusinessObjectForPictogramElement(pe);
    	if (bo instanceof JavaPersistentType) {
    		jpt = (JavaPersistentType)bo;
    		hasNameAnnotation = JpaArtifactFactory.instance().hasNameAnnotation(jpt);
    		return true;
    	}
    	if (pe instanceof Shape) {
    		ContainerShape cs = ((Shape)pe).getContainer();
    		if (cs == null)
    			return false;
     		bo = getFeatureProvider().getBusinessObjectForPictogramElement(cs);
        	if (bo instanceof JavaPersistentType) {
        		jpt = (JavaPersistentType)bo;
        		hasNameAnnotation = JpaArtifactFactory.instance().hasNameAnnotation(jpt);
        		return true;
        	}
    	}    	
		return false;
	}
	
	@Override
	public boolean canExecute(ICustomContext context) {
		return true;
	}
	
	public void execute(ICustomContext context, SelectionDispatchAction action, ICompilationUnit cu) {
		StructuredSelection sel = new StructuredSelection(cu);
		final Shape pict = (Shape)getFeatureProvider().getPictogramElementForBusinessObject(jpt);
		JavaPersistentType jpt = (JavaPersistentType)getFeatureProvider().
									getBusinessObjectForPictogramElement(pict);
		final JPAEditorConstants.DIAGRAM_OBJECT_TYPE dot = JpaArtifactFactory.instance().determineDiagramObjectType(jpt);
		final PersistenceUnit pu = JpaArtifactFactory.instance().getPersistenceUnit(jpt);
		final Semaphore s = new Semaphore(0);
		final JPAProjectListener lsnr = new JPAProjectListener(s);
		jpt.getJpaProject().addCollectionChangeListener(JpaProject.JPA_FILES_COLLECTION, lsnr);
		ShowBusy showBusy = new ShowBusy(s);
		JPASolver.ignoreEvents = true;
		final String oldName = jpt.getName();
		
		try {
			action.run(sel);
		} catch (Exception e) {} 
		BusyIndicator.showWhile(Display.getCurrent(), showBusy);
		jpt.getJpaProject().removeCollectionChangeListener(JpaProject.JPA_FILES_COLLECTION, lsnr);
		JPASolver.ignoreEvents = false;
		final boolean rename = RenameEntityFeature.class.isInstance(this);
		
		if (!showBusy.isMoved()) 
			return;
		
		TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(pict);
		ted.getCommandStack().execute(new RecordingCommand(ted) {
			@Override
			protected void doExecute() {
				remapEntity(oldName, pict, pu, rename, lsnr, dot, getFeatureProvider());
			}
		});	
	}
	
	public void execute(ICustomContext context, String newName, ICompilationUnit cu, JavaPersistentType jpt) {
		final JPAEditorConstants.DIAGRAM_OBJECT_TYPE dot = JpaArtifactFactory.instance().determineDiagramObjectType(jpt);
		final String oldName = jpt.getName();
		final Shape pict = (Shape)getFeatureProvider().getPictogramElementForBusinessObject(jpt);
		jpt = (JavaPersistentType)getFeatureProvider().
									getBusinessObjectForPictogramElement(pict);		
		final PersistenceUnit pu = JpaArtifactFactory.instance().getPersistenceUnit(jpt);
		final Semaphore s = new Semaphore(0);
		final JPAProjectListener lsnr = new JPAProjectListener(s);
		jpt.getJpaProject().addCollectionChangeListener(JpaProject.JPA_FILES_COLLECTION, lsnr);
		ShowBusy showBusy = new ShowBusy(s);
		JPASolver.ignoreEvents = true;
		JpaArtifactFactory.instance().renameEntityClass(jpt, newName, getFeatureProvider());		
		BusyIndicator.showWhile(Display.getCurrent(), showBusy);
		jpt.getJpaProject().removeCollectionChangeListener(JpaProject.JPA_FILES_COLLECTION, lsnr);
		JPASolver.ignoreEvents = false;		
		TransactionalEditingDomain ted = TransactionUtil.getEditingDomain(pict);
		ted.getCommandStack().execute(new RecordingCommand(ted) {
			@Override
			protected void doExecute() {
				remapEntity(oldName, pict, pu, true, lsnr, dot, getFeatureProvider());
			}
		});
	}
	
	public static void remapEntity(final String oldName,
								   final Shape pict,
								   final PersistenceUnit pu,
								   final boolean rename,
								   final JPAProjectListener lsnr,
								   final JPAEditorConstants.DIAGRAM_OBJECT_TYPE dot,
								   final IJPAEditorFeatureProvider fp) {
		BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
			public void run() {
				// TODO figure out why this was necessary:
				// pu.getJpaProject().updateAndWait();
				final int x = pict.getGraphicsAlgorithm().getX();
				final int y = pict.getGraphicsAlgorithm().getY();
				final int width = pict.getGraphicsAlgorithm().getWidth();
				final int height = pict.getGraphicsAlgorithm().getHeight();		
				
				final ContainerShape cs = Graphiti.getPeService().createContainerShape(fp.getDiagramTypeProvider().getDiagram(), 
						true);
				cs.setVisible(true);
				
				AddContext cont = new AddContext();
				cont.setX(x);
				cont.setY(y);
				cont.setWidth(width);
				cont.setHeight(height);
				RoundedRectangle rect = AddJPAEntityFeature.createEntityRectangle(cont, cs, dot, fp.getDiagramTypeProvider().getDiagram()); 	
				rect.setFilled(true);
				
				IRemoveContext ctx = new RemoveContext(pict); 
				RemoveJPAEntityFeature ft = new RemoveJPAEntityFeature(fp, true);
				
				boolean primaryCollapsed = JPAEditorConstants.TRUE_STRING.equals(Graphiti.getPeService().getPropertyValue(pict, JPAEditorConstants.PRIMARY_COLLAPSED));
				boolean relationCollapsed = JPAEditorConstants.TRUE_STRING.equals(Graphiti.getPeService().getPropertyValue(pict, JPAEditorConstants.RELATION_COLLAPSED));
				boolean basicCollapsed = JPAEditorConstants.TRUE_STRING.equals(Graphiti.getPeService().getPropertyValue(pict, JPAEditorConstants.BASIC_COLLAPSED));

				AddEntityContext addCtx = new AddEntityContext(primaryCollapsed, relationCollapsed, basicCollapsed);
				String newJPTName = lsnr.getNewJPTName();
				
				JavaPersistentType newJPT = JpaArtifactFactory.instance().getJPT(newJPTName, pu);
				if (!JptJpaCorePlugin.getDiscoverAnnotatedClasses(newJPT.getJpaProject().getProject())) {
					JPAEditorUtil.createUnregisterEntityFromXMLJob(newJPT.getJpaProject(), oldName);
				}									
				if (rename) {
					String tableName = JPAEditorUtil.formTableName(newJPT);
					JpaArtifactFactory.instance().setTableName(newJPT, tableName);
				}
				addCtx.setNewObject(newJPT);
				addCtx.setTargetContainer(fp.getDiagramTypeProvider().getDiagram());
				addCtx.setX(x);
				addCtx.setY(y);
				addCtx.setWidth(width);
				addCtx.setHeight(height);
				AddJPAEntityFeature ft1 = new AddJPAEntityFeature(fp, true);
				ft.remove(ctx);
				ft1.add(addCtx);
				PictogramElement pe = fp.getPictogramElementForBusinessObject(newJPT);
				fp.getDiagramTypeProvider().getDiagramEditor().setPictogramElementForSelection(pe);
				Graphiti.getPeService().deletePictogramElement(cs);	
				
				JpaArtifactFactory.instance().refreshEntityModel(fp, newJPT);
				if (!JptJpaCorePlugin.getDiscoverAnnotatedClasses(newJPT.getJpaProject().getProject())) {
					JPAEditorUtil.createRegisterEntityInXMLJob(newJPT.getJpaProject(), newJPTName);
				}
			}
		});
		
	}
	
	
	
	@Override
	protected Diagram getDiagram() {
		return getFeatureProvider().getDiagramTypeProvider().getDiagram();
	}	
	
	@Override
	public IJPAEditorFeatureProvider getFeatureProvider() {
		return (IJPAEditorFeatureProvider)super.getFeatureProvider();
	}
	
	class ShowBusy implements Runnable {
		private Semaphore s;
		boolean moved = false;
		ShowBusy(Semaphore s) {
			this.s = s;
		}
		
		public void run() {
			try {
				moved = s.tryAcquire(2, 4, TimeUnit.SECONDS);
			} catch (InterruptedException e) {
				JPADiagramEditorPlugin.logError("Thread interrupted", e);  //$NON-NLS-1$		 							
			}
		}

		boolean isMoved() {
			return moved;
		}		
	}
	
	public class JPAProjectListener implements CollectionChangeListener {
		private Semaphore s = null;
		private String newJptName = null;
		
		public JPAProjectListener(Semaphore s) {
			this.s = s;
		}
						
		public void itemsAdded(CollectionAddEvent event) {
			Iterator<?> it = event.getItems().iterator();
			Object o = it.next();
			JpaFile jpaFile = (JpaFile)o;
			
			JptResourceModel rm = jpaFile.getResourceModel();
			if (rm == null)
				return;
			if (!JavaResourceCompilationUnit.class.isInstance(rm))
				return;
			JavaResourceCompilationUnit jrcu = (JavaResourceCompilationUnit)rm;
			JavaResourceAbstractType jrt = jrcu.getPrimaryType();		
			newJptName = jrt.getQualifiedName();
			s.release();
			if ((ats == null) || hasNameAnnotation)
				return;
			final Iterator<JavaPersistentAttribute> iter = ats.iterator();
			Runnable r = new Runnable() {
				public void run() {
					Hashtable<String, String> atOldToNewName = new Hashtable<String, String>();
					Set<JavaPersistentAttribute> newSelfAts = new HashSet<JavaPersistentAttribute>();
					while (iter.hasNext()) {
						JavaPersistentAttribute at = iter.next();
						ICompilationUnit cu = getFeatureProvider().getCompilationUnit((JavaPersistentType) at.getParent());
						if (!cu.exists()) {
							at = (JavaPersistentAttribute)at.getPersistenceUnit().getPersistentType(newJptName).getAttributeNamed(at.getName());
							JavaPersistentAttribute newAt = null;
							try {
								newAt = JpaArtifactFactory.instance().renameAttribute(at, JPAEditorUtil.returnSimpleName(newJptName), newJptName, getFeatureProvider());
							} catch (InterruptedException e) {
								JPADiagramEditorPlugin.logError(e);
							}
							atOldToNewName.put(at.getName(), newAt.getName());
							newSelfAts.add(newAt);
						} else {
							try {
								JpaArtifactFactory.instance().renameAttribute(at, JPAEditorUtil.returnSimpleName(newJptName), newJptName, getFeatureProvider());
							} catch (InterruptedException e) {
								JPADiagramEditorPlugin.logError(e);
							}
						}
					}
					Iterator<JavaPersistentAttribute> itr =  newSelfAts.iterator();
					while (itr.hasNext()) {
						JavaPersistentAttribute at = itr.next();
						JpaArtifactFactory.instance().refreshEntityModel(null, (JavaPersistentType)at.getParent());
						JavaAttributeMapping m = at.getMapping();
						Annotation mappingAnnotation = m.getMappingAnnotation();
											
						if(mappingAnnotation == null){
							JpaArtifactFactory.instance().refreshEntityModel(getFeatureProvider(), (JavaPersistentType)at.getParent());
							mappingAnnotation = m.getMappingAnnotation();
						}	
						if (mappingAnnotation == null)
							return;
						if (OwnableRelationshipMappingAnnotation.class.isInstance(mappingAnnotation)) {
							OwnableRelationshipMappingAnnotation ownableMappingAnnotation = (OwnableRelationshipMappingAnnotation)mappingAnnotation;
							String oldMappedBy = ownableMappingAnnotation.getMappedBy();
							if (oldMappedBy != null) {
								String newMappedBy = atOldToNewName.get(oldMappedBy);
								if (newMappedBy != null)
									ownableMappingAnnotation.setMappedBy(newMappedBy);
							}
						}
					}
					
				}				
			};
			Display.getDefault().asyncExec(r);
		}

		public void itemsRemoved(CollectionRemoveEvent arg0) {
			s.release();
		}

		public void collectionChanged(CollectionChangeEvent event) {
		}
		
		public void collectionCleared(CollectionClearEvent arg0) {}
		
		public String getNewJPTName() {
			return newJptName;
		}
		

	};
	

}
