/******************************************************************************
 * Copyright (c) 2009 Red Hat
 * 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:
 *    Rob Stryker - initial implementation and ongoing maintenance
 ******************************************************************************/
package org.eclipse.jst.j2ee.internal.ui.preferences;

import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.jst.common.jdt.internal.javalite.JavaCoreLite;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants.DependencyAttributeType;
import org.eclipse.jst.j2ee.classpathdep.UpdateClasspathAttributeUtil;
import org.eclipse.jst.j2ee.internal.ManifestUIResourceHandler;
import org.eclipse.jst.j2ee.internal.actions.IJ2EEUIContextIds;
import org.eclipse.jst.j2ee.internal.modulecore.util.DummyClasspathDependencyContainerVirtualComponent;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.ui.internal.propertypage.IReferenceEditor;
import org.eclipse.wst.common.componentcore.ui.internal.taskwizard.IWizardHandle;
import org.eclipse.wst.common.componentcore.ui.internal.taskwizard.WizardFragment;
import org.eclipse.wst.common.componentcore.ui.propertypage.IReferenceWizardConstants;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation;
import org.eclipse.wst.common.frameworks.internal.ui.WTPUIPlugin;
import org.eclipse.wst.common.frameworks.internal.ui.WorkspaceModifyComposedOperation;

/**
 * Handle the case of ears pulling in stuff from children
 * @author rob
 *
 */
public class ClasspathDependencyWizardFragment extends WizardFragment implements IReferenceEditor {

	private CheckboxTreeViewer viewer;
	private IWizardHandle handle;
	private HashMap<IProject, WrappedClasspathEntry[]> map = new HashMap<IProject, WrappedClasspathEntry[]>();
	private ArrayList<WrappedClasspathEntry> originallyChecked = new ArrayList<WrappedClasspathEntry>();
	public ClasspathDependencyWizardFragment() {
	}

	boolean isComplete = false;

	@Override
	public boolean isComplete() {
		return isComplete;
	}
	
	@Override
	public boolean hasComposite() {
		return true;
	}

	public boolean canEdit(IVirtualReference ref) {
		return ref.getReferencedComponent() instanceof DummyClasspathDependencyContainerVirtualComponent;
	}
	
	@Override
	public Composite createComposite(Composite parent, IWizardHandle handle) {
		this.handle = handle;
		Composite c = new Composite(parent, SWT.NONE);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(c, IJ2EEUIContextIds.DEPLOYMENT_ASSEMBLY_PREFERENCE_PAGE_ADD_REFERENCED_PROJECT_CLASSPATH_ENTRIES);
		c.setLayout(new GridLayout());
		handle.setTitle(Messages.ClasspathDependencyFragmentTitle);
		handle.setDescription(Messages.ClasspathDependencyFragmentDescription);
		viewer = new CheckboxTreeViewer(c);
	    viewer.setContentProvider(new ClasspathPushupContentProvider());
	    viewer.setLabelProvider(new ClasspathPushupLabelProvider());
	    try {
	    	loadModel();
	    } catch( Exception e) {e.printStackTrace();}
	    viewer.setInput(ResourcesPlugin.getPlugin()); // ignored
	    viewer.expandAll();
	    viewer.setGrayedElements(getSuitableProjects());
	    viewer.setCheckedElements(originallyChecked.toArray(new WrappedClasspathEntry[originallyChecked.size()]));
	    viewer.addCheckStateListener(new ICheckStateListener() {
	        public void checkStateChanged(CheckStateChangedEvent event) {
	        	handleCheckEvent(event);
	        }
	      });
	    GridData data = new GridData(GridData.FILL_BOTH);
		data.widthHint = 390;
		data.heightHint = 185;
		viewer.getTree().setLayoutData(data);
		return c;
	}
	
	protected void handleCheckEvent(CheckStateChangedEvent event) {
        if (event.getChecked()) {
            // cannot check projects
        	if( event.getElement() instanceof IProject ) 
        		viewer.setChecked(event.getElement(), false);
        }
        // Set the result for later
        if( event.getElement() instanceof WrappedClasspathEntry ) {
        	WrappedClasspathEntry wce = ((WrappedClasspathEntry)event.getElement());
        	wce.postStatus = event.getChecked();
        }
        
        Iterator<IProject> i = map.keySet().iterator();
        boolean hasChanged = false;
		while(i.hasNext()) {
			IProject p = i.next();
			WrappedClasspathEntry[] entries = map.get(p);
			for( int j = 0; j < entries.length; j++ ) {
				if( entries[j].postStatus != entries[j].preStatus) {
					hasChanged = true;
					break;
				}
			}
			if(hasChanged)
				break;
		}
		if(isComplete != hasChanged) {
			isComplete = hasChanged;
			handle.update();
		}				
	}

	// label provider
	private class ClasspathPushupLabelProvider extends LabelProvider {
		private Image classpathImage = null;
		
		@Override
	    public void dispose() {
	    	super.dispose();
	    	if( classpathImage != null && !classpathImage.isDisposed())
	    		classpathImage.dispose();
	    }
		
	    @Override
		public Image getImage(Object element) {
			if( element instanceof IProject )
				return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_PROJECT);
			if (classpathImage == null) {
				ImageDescriptor imageDescriptor = null;
				URL gifImageURL = (URL) J2EEPlugin.getPlugin().getImage("CPDep"); //$NON-NLS-1$
				imageDescriptor = ImageDescriptor.createFromURL(gifImageURL);
				classpathImage = imageDescriptor.createImage();
			}
			return classpathImage;
		}
		@Override
		public String getText(Object element) {
			if( element instanceof IProject )
				return ((IProject)element).getName();
			if(element instanceof WrappedClasspathEntry) {
				try {
					WrappedClasspathEntry entry = (WrappedClasspathEntry)element;
					if (entry.entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
						final IClasspathContainer container = JavaCore.getClasspathContainer(
								entry.entry.getPath(), JavaCore.create(entry.project));
						if (container != null) {
							return container.getDescription();
						}
					}
					else {
						// use path for non-container type classpath entries
						return entry.entry.getPath().toOSString();
					}
				} catch( JavaModelException jme) {
					// ignore
				}
			}
			return element == null ? "" : element.toString();//$NON-NLS-1$
		}
	}
	
	// wrap classpath entries into a slightly more useful form
	private WrappedClasspathEntry[] wrapClasspathEntries(IClasspathEntry[] entries, IProject project, boolean preStatus) {
		WrappedClasspathEntry[] results = new WrappedClasspathEntry[entries.length];
		for( int i = 0; i < entries.length; i++ )
			results[i] = new WrappedClasspathEntry(entries[i], project, preStatus, preStatus);
		return results;
	}
	
	// class that can cache the entry, project, and pre and post status of the attribute
	private class WrappedClasspathEntry {
		public IClasspathEntry entry;
		public IProject project;
		boolean preStatus;
		boolean postStatus;
		public WrappedClasspathEntry(IClasspathEntry entry2, IProject project2, boolean preStatus2, boolean postStatus2) {
			this.entry = entry2;
			this.project = project2;
			this.preStatus = preStatus2;
			this.postStatus = postStatus2;
		}
	}
	
	private class ClasspathPushupContentProvider implements ITreeContentProvider {
		public Object[] getChildren(Object parentElement) {
			if( parentElement instanceof IProject ) {
				Object[] ret = map.get(parentElement);
				return ret == null ? new Object[]{} : ret;
			}
			return new Object[]{};
		}

		
		public Object getParent(Object element) {
			return null;
		}

		public boolean hasChildren(Object element) {
			return getChildren(element).length > 0;
		}

		public Object[] getElements(Object inputElement) {
			// return suitable projects
			return getSuitableProjects();
		}
		
		public void dispose() {
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}
	}
	
	// creating the individual pieces
	private WrappedClasspathEntry[] loadEntriesForProject(IProject parentElement) {
		ArrayList<WrappedClasspathEntry> ret = new ArrayList<WrappedClasspathEntry>();
		try {
			Map <IClasspathEntry, IClasspathAttribute> results = 
				ClasspathDependencyUtil.getRawComponentClasspathDependencies(
					JavaCoreLite.create(parentElement), 
							DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY);
			
			Set<IClasspathEntry> setResult = results.keySet();
			IClasspathEntry[] setResultArray = 
				setResult.toArray(new IClasspathEntry[setResult.size()]);
			WrappedClasspathEntry[] wrappedArray = wrapClasspathEntries(setResultArray, parentElement, true);
			originallyChecked.addAll(Arrays.asList(wrappedArray));
			ret.addAll(Arrays.asList(wrappedArray));
			
			List<IClasspathEntry> potentialList = 
				ClasspathDependencyUtil.getPotentialComponentClasspathDependencies(
						JavaCoreLite.create(parentElement));
			IClasspathEntry[] potentials = potentialList.toArray(new IClasspathEntry[potentialList.size()]);
			ret.addAll(Arrays.asList(wrapClasspathEntries(potentials, parentElement, false)));
		} catch( CoreException ce ) {
			// ignore
		}
		return ret.toArray(new WrappedClasspathEntry[ret.size()]);
	}

	// Only projects with java nature are suitable here
	protected IProject[] getSuitableProjects() {
		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		ArrayList<IProject> projs = new ArrayList<IProject>();
		for( int i = 0; i < projects.length; i++ ) {
			try {
				if( projects[i].hasNature(JavaCoreLite.NATURE_ID) && ModuleCoreNature.isFlexibleProject(projects[i]))
					projs.add(projects[i]);
			} catch( CoreException ce) {
				// ignore
			}
		}
		return projs.toArray(new IProject[projs.size()]);
	}
	
	protected void loadModel() {
		IProject[] projects = getSuitableProjects();
		for( int i = 0; i < projects.length; i++ ) {
			map.put(projects[i], loadEntriesForProject(projects[i]));
		}
	}
	
	@Override
	public void performFinish(IProgressMonitor monitor) throws CoreException {
		// iterate through and actually change the stuff
		boolean anyChecked = false;
		Iterator<IProject> i = map.keySet().iterator();
		final WorkspaceModifyComposedOperation composedOp = new WorkspaceModifyComposedOperation();
		while(i.hasNext()) {
			IProject p = i.next();
			WrappedClasspathEntry[] entries = map.get(p);
			ArrayList<WrappedClasspathEntry> changed = new ArrayList<WrappedClasspathEntry>();
			for( int j = 0; j < entries.length; j++ ) {
				if( entries[j].postStatus) anyChecked = true;
				if( entries[j].preStatus != entries[j].postStatus) {
					changed.add(entries[j]);
				}
			}
			if( !changed.isEmpty()) {
				prepareChanges(composedOp, changed, p);
			}
		}
		try {
			composedOp.run(new NullProgressMonitor());
		} catch( InvocationTargetException e ) {
			final InvocationTargetException ex2 = e;
			Display.getCurrent().asyncExec(new Runnable() {
				public void run() {
						final Shell shell = ((WizardPage)handle).getShell();
						String title = ManifestUIResourceHandler.An_internal_error_occurred_ERROR_;
						String msg = title;
						if (ex2.getTargetException() != null && ex2.getTargetException().getMessage() != null)
							msg = ex2.getTargetException().getMessage();
						MessageDialog.openError(shell, title, msg);
						org.eclipse.jem.util.logger.proxy.Logger.getLogger().logError(ex2);
				}
			});
		} catch (InterruptedException e) {
			// ignore
		}
		
		if( anyChecked ) {
			IProject project = (IProject)getTaskModel().getObject(IReferenceWizardConstants.PROJECT);
			IVirtualComponent root = (IVirtualComponent)getTaskModel().getObject(IReferenceWizardConstants.ROOT_COMPONENT);
			IVirtualComponent imported = new DummyClasspathDependencyContainerVirtualComponent(project, root);
			VirtualReference ref = new VirtualReference(root, imported);
			ref.setDerived(true);
			ref.setRuntimePath(new Path("/")); //$NON-NLS-1$
			getTaskModel().putObject(IReferenceWizardConstants.FINAL_REFERENCE, ref); 
		} else {
			getTaskModel().putObject(IReferenceWizardConstants.FINAL_REFERENCE, null);
		}
	}

	protected void prepareChanges(WorkspaceModifyComposedOperation composedOp, 
			ArrayList<WrappedClasspathEntry> elements, IProject project) {
		final Map<IClasspathEntry, IPath> selectedEntriesToRuntimePath = new HashMap<IClasspathEntry, IPath>();
		final Map<IClasspathEntry, IPath> unselectedEntriesToRuntimePath = new HashMap<IClasspathEntry, IPath>();
		final IPath runtimePath = IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH; 
		
		for (int i = 0; i < elements.size(); i++) {
			WrappedClasspathEntry wrapped = elements.get(i);
			final IClasspathEntry entry = wrapped.entry;
			if( !wrapped.preStatus && wrapped.postStatus )
				selectedEntriesToRuntimePath.put(entry, runtimePath);
			else if( wrapped.preStatus && !wrapped.postStatus) 
				unselectedEntriesToRuntimePath.put(entry, runtimePath);
		}
		
		// if there are any attributes to add, create an operation to add all necessary attributes 
		if (!selectedEntriesToRuntimePath.isEmpty()) {
			IDataModelOperation op = UpdateClasspathAttributeUtil.createAddDependencyAttributesOperation(project.getName(), selectedEntriesToRuntimePath); 
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(op));
		}
		
		// if there are any attributes to remove, create an operation to remove all necessary attributes
		if (!unselectedEntriesToRuntimePath.isEmpty()) {
			IDataModelOperation op = UpdateClasspathAttributeUtil.createRemoveDependencyAttributesOperation(project.getName(), unselectedEntriesToRuntimePath); 
			composedOp.addRunnable(WTPUIPlugin.getRunnableWithProgress(op));
		}
	}
}
