/*******************************************************************************
 * Copyright (c) 2003, 2005 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.classpath;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.common.jdt.internal.classpath.ClasspathDecorations;
import org.eclipse.jst.common.jdt.internal.classpath.ClasspathDecorationsManager;
import org.eclipse.jst.j2ee.internal.common.J2EECommonMessages;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.builder.DependencyGraphManager;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;

/**
 * This classpath container is based on the Component references; not the manifest entries. Other
 * mechanisms are in place to ensure that the component references are updated when the manifest is
 * updated, and also to make sure the manifest is updated when the component references are updated.
 * 
 */
public class J2EEComponentClasspathContainer implements IClasspathContainer {

	public static final String CONTAINER_ID = "org.eclipse.jst.j2ee.internal.module.container"; //$NON-NLS-1$
	public static final IPath CONTAINER_PATH = new Path(CONTAINER_ID);

	private static IPath WEBLIB = new Path("/WEB-INF/lib"); //$NON-NLS-1$
	
	private static ClasspathDecorationsManager decorationsManager = new ClasspathDecorationsManager(J2EEPlugin.PLUGIN_ID);

	public static ClasspathDecorationsManager getDecorationsManager() {
        return decorationsManager;
    }
	
	private IPath containerPath;
	private IJavaProject javaProject;
	private IClasspathEntry[] entries = new IClasspathEntry[0];
	private static Map keys = new Hashtable();
	private static Map previousSelves = new Hashtable();
	
	private class LastUpdate {
		private int refCount = 0;
		private boolean[] isBinary = new boolean[refCount];
		private IPath[] paths = new IPath[refCount];
	}

	private LastUpdate lastUpdate = new LastUpdate();

	public J2EEComponentClasspathContainer(IPath path, IJavaProject javaProject) {
		this.containerPath = path;
		this.javaProject = javaProject;
	}

	private boolean requiresUpdate() {
		IVirtualComponent component = ComponentCore.createComponent(javaProject.getProject());
		if (component == null) {
			return false;
		}
		IVirtualReference[] refs = component.getReferences();
		IVirtualComponent comp = null;

		// avoid updating the container if references haven't changed
		if (refs.length == lastUpdate.refCount) {
			for (int i = 0; i < lastUpdate.refCount; i++) {
				comp = refs[i].getReferencedComponent();
				if (comp.isBinary() != lastUpdate.isBinary[i]) {
					return true;
				} else {
					IPath path = null;
					if (comp.isBinary()) {
						VirtualArchiveComponent archiveComp = (VirtualArchiveComponent) comp;
						java.io.File diskFile = archiveComp.getUnderlyingDiskFile();
						if (diskFile.exists())
							path = new Path(diskFile.getAbsolutePath());
						else {
							IFile iFile = archiveComp.getUnderlyingWorkbenchFile();
							path = iFile.getFullPath();
						}
					} else {
						path = comp.getProject().getFullPath();
					}
					if (!path.equals(lastUpdate.paths[i])) {
						return true;
					}
				}
			}
			return false;
		}
		return true;
	}
	
	private void update() {
		IVirtualComponent component = ComponentCore.createComponent(javaProject.getProject());
		Object key = keys.get(new Integer(javaProject.getProject().hashCode()));
		J2EEComponentClasspathContainer firstPreviousSelf = (J2EEComponentClasspathContainer)previousSelves.get(key);
		if (component == null) {
			return;
		}
		
		IVirtualComponent comp = null;
		IVirtualReference ref = null;
		
		IVirtualReference[] refs = component.getReferences();
		List refsList = new ArrayList();
		for(int i = 0; i<refs.length;i++){
			refsList.add(refs[i]);
		}
		for(int i=0; i< refsList.size(); i++){
			comp = ((IVirtualReference)refsList.get(i)).getReferencedComponent();
			if(comp.isBinary()){
				IVirtualReference [] binaryRefs = comp.getReferences();
				for(int j = 0; j<binaryRefs.length; j++){
					if(!refsList.contains(binaryRefs[j])){
						refsList.add(binaryRefs[j]);
					}
				}
			}
		}
		
		lastUpdate.refCount = refsList.size();
		lastUpdate.isBinary = new boolean[lastUpdate.refCount];
		lastUpdate.paths = new IPath[lastUpdate.refCount];

		boolean isWeb = J2EEProjectUtilities.isDynamicWebProject(component.getProject());
		boolean shouldAdd = true;

		List entriesList = new ArrayList();

		try {
			IJavaProject javaProject = JavaCore.create(component.getProject());
			Set existingEntries = new HashSet();
			try {
				IClasspathContainer container = JavaCore.getClasspathContainer(CONTAINER_PATH, javaProject);
				List previousEntries = null;
				if(null != container){
					final IClasspathEntry[] containerEntries = container.getClasspathEntries();
					previousEntries = Arrays.asList(containerEntries);
				}
				existingEntries.addAll(Arrays.asList(javaProject.getResolvedClasspath(true)));
				if(null != previousEntries){
					existingEntries.removeAll(previousEntries);
				}
				if(firstPreviousSelf != null){
					existingEntries.removeAll(Arrays.asList(firstPreviousSelf.entries));
				}
				J2EEComponentClasspathContainer secondPreviousSelf = (J2EEComponentClasspathContainer)previousSelves.get(key);
				if(firstPreviousSelf != secondPreviousSelf && secondPreviousSelf != null){
					existingEntries.removeAll(Arrays.asList(secondPreviousSelf.entries));
				}
				
				existingEntries.removeAll(Arrays.asList(entries));
			
			} catch (JavaModelException e) {
				Logger.getLogger().logError(e);
			}
			for (int i = 0; i < refsList.size(); i++) {
				ref = (IVirtualReference)refsList.get(i);
				comp = ref.getReferencedComponent();
				lastUpdate.isBinary[i] = comp.isBinary();
				shouldAdd = !(isWeb && ref.getRuntimePath().equals(WEBLIB));
				if (!shouldAdd) {
					continue;
				}
				if (comp.isBinary()) {
					VirtualArchiveComponent archiveComp = (VirtualArchiveComponent) comp;
					java.io.File diskFile = archiveComp.getUnderlyingDiskFile();
					if (diskFile.exists()) {
						lastUpdate.paths[i] = new Path(diskFile.getAbsolutePath());
					} else {
						IFile iFile = archiveComp.getUnderlyingWorkbenchFile();
						lastUpdate.paths[i] = iFile.getFullPath();
					}
					if (!isAlreadyOnClasspath(existingEntries, lastUpdate.paths[i])) {
						ClasspathDecorations dec = decorationsManager.getDecorations( getPath().toString(), lastUpdate.paths[i].toString() );
						
						IPath srcpath = null;
				        IPath srcrootpath = null;
				        IClasspathAttribute[] attrs = {};
				        IAccessRule[] access = {};
						
				        if( dec != null ) {
				            srcpath = dec.getSourceAttachmentPath();
				            srcrootpath = dec.getSourceAttachmentRootPath();
				            attrs = dec.getExtraAttributes();
				        }
			        
				        entriesList.add(JavaCore.newLibraryEntry( lastUpdate.paths[i], srcpath, srcrootpath, access, attrs, true ));
					}
				} else {
					IProject project = comp.getProject();
					lastUpdate.paths[i] = project.getFullPath();
					if (!isAlreadyOnClasspath(existingEntries, lastUpdate.paths[i])) {
						entriesList.add(JavaCore.newProjectEntry(lastUpdate.paths[i], true));
					}
				}
			}
		} finally {
			entries = new IClasspathEntry[entriesList.size()];
			for (int i = 0; i < entries.length; i++) {
				entries[i] = (IClasspathEntry) entriesList.get(i);
			}
		}
		previousSelves.put(key, this);
	}

	public static void install(IPath containerPath, IJavaProject javaProject) {
		try{
			J2EEComponentClasspathUpdater.getInstance().pauseUpdates();
			Integer hashCode = new Integer(javaProject.getProject().hashCode());
			Object key = keys.get(hashCode);
			if(key == null){
				keys.put(hashCode, hashCode);
				key = hashCode;
			}
			final IJavaProject[] projects = new IJavaProject[]{javaProject};
			final J2EEComponentClasspathContainer container = new J2EEComponentClasspathContainer(containerPath, javaProject);
			container.update();
			final IClasspathContainer[] conts = new IClasspathContainer[]{container};
			try {
				JavaCore.setClasspathContainer(containerPath, projects, conts, null);
				previousSelves.put(key, container);
			} catch (JavaModelException e) {
				Logger.getLogger().log(e);
			}
		} finally {
			J2EEComponentClasspathUpdater.getInstance().resumeUpdates();
		}
	}

	public void refresh(boolean force){
		if(force || requiresUpdate()){
			install(containerPath, javaProject);
			// Update dependency graph
			DependencyGraphManager.getInstance().forceRefresh();
		}
	}
	
	public void refresh() {
		refresh(false);
	}

	public IClasspathEntry[] getClasspathEntries() {
		return entries;
	}

	public String getDescription() {
		return J2EECommonMessages.J2EE_MODULE_CLASSPATH_CONTAINER_NAME;
	}

	public int getKind() {
		return K_APPLICATION;
	}

	public IPath getPath() {
		return containerPath;
	}

	/**
	 * Taken from {@link JavaProject#isOnClasspath(org.eclipse.core.resources.IResource)}
	 * 
	 * @param classpath
	 * @param newPath
	 * @return
	 */
	private static boolean isAlreadyOnClasspath(Set classpath, IPath newPath) {
		for (Iterator itr = classpath.iterator(); itr.hasNext();) {
			IClasspathEntry entry = (IClasspathEntry) itr.next();
			IPath entryPath = entry.getPath();
			if (entryPath.equals(newPath)) { // package fragment roots must match exactly entry
				// pathes (no exclusion there)
				return true;
			}
			if (entryPath.isPrefixOf(newPath) && !Util.isExcluded(newPath, ((ClasspathEntry) entry).fullInclusionPatternChars(), ((ClasspathEntry) entry).fullExclusionPatternChars(), false)) {
				return true;
			}
		}
		return false;
	}
}