/*******************************************************************************
 * Copyright (c) 2000, 2017 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.dltk.internal.core;

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

import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IModelElementDelta;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.search.indexing.IndexManager;
import org.eclipse.dltk.internal.core.ModelManager.PerProjectInfo;
import org.eclipse.dltk.internal.core.search.ProjectIndexerManager;

public class BuildpathChange {
	public static int NO_DELTA = 0x00;
	public static int HAS_DELTA = 0x01;
	public static int HAS_PROJECT_CHANGE = 0x02;
	public static int HAS_LIBRARY_CHANGE = 0x04;

	ScriptProject project;
	IBuildpathEntry[] oldRawBuildpath;
	IBuildpathEntry[] oldResolvedBuildpath;

	public BuildpathChange(ScriptProject project,
			IBuildpathEntry[] oldRawBuildpath,
			IBuildpathEntry[] oldResolvedBuildpath) {
		this.project = project;
		this.oldRawBuildpath = oldRawBuildpath;
		this.oldResolvedBuildpath = oldResolvedBuildpath;
	}

	private void addBuildpathDeltas(ModelElementDelta delta,
			IProjectFragment[] roots, int flag) {
		for (int i = 0; i < roots.length; i++) {
			IProjectFragment root = roots[i];
			delta.changed(root, flag);
			if ((flag & IModelElementDelta.F_REMOVED_FROM_BUILDPATH) != 0
			/*
			 * || (flag & IModelElementDelta.F_SOURCEATTACHED) != 0 || (flag &
			 * IModelElementDelta.F_SOURCEDETACHED) != 0
			 */) {
				try {
					root.close();
				} catch (ModelException e) {
					// ignore
				}
			}
		}
	}

	/*
	 * Returns the index of the item in the list if the given list contains the
	 * specified entry. If the list does not contain the entry, -1 is returned.
	 */
	private int buildpathContains(IBuildpathEntry[] list,
			IBuildpathEntry entry) {
		IPath[] exclusionPatterns = entry.getExclusionPatterns();
		IPath[] inclusionPatterns = entry.getInclusionPatterns();
		int listLen = list == null ? 0 : list.length;
		nextEntry: for (int i = 0; i < listLen; i++) {
			IBuildpathEntry other = list[i];
			if (other.getContentKind() == entry.getContentKind()
					&& other.getEntryKind() == entry.getEntryKind()
					&& other.isExported() == entry.isExported()
					&& other.getPath().equals(entry.getPath())) {

				// check inclusion patterns
				IPath[] otherIncludes = other.getInclusionPatterns();
				if (inclusionPatterns != otherIncludes) {
					if (inclusionPatterns == null)
						continue;
					int includeLength = inclusionPatterns.length;
					if (otherIncludes == null
							|| otherIncludes.length != includeLength)
						continue;
					for (int j = 0; j < includeLength; j++) {
						// compare toStrings instead of IPaths
						// since IPath.equals is specified to ignore trailing
						// separators
						if (!inclusionPatterns[j].toString()
								.equals(otherIncludes[j].toString()))
							continue nextEntry;
					}
				}
				// check exclusion patterns
				IPath[] otherExcludes = other.getExclusionPatterns();
				if (exclusionPatterns != otherExcludes) {
					if (exclusionPatterns == null)
						continue;
					int excludeLength = exclusionPatterns.length;
					if (otherExcludes == null
							|| otherExcludes.length != excludeLength)
						continue;
					for (int j = 0; j < excludeLength; j++) {
						// compare toStrings instead of IPaths
						// since IPath.equals is specified to ignore trailing
						// separators
						if (!exclusionPatterns[j].toString()
								.equals(otherExcludes[j].toString()))
							continue nextEntry;
					}
				}
				return i;
			}
		}
		return -1;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof BuildpathChange))
			return false;
		return this.project.equals(((BuildpathChange) obj).project);
	}

	/*
	 * Generates a buildpath change delta for this buildpath change. Returns
	 * whether a delta was generated, and whether project reference have
	 * changed.
	 */
	public int generateDelta(ModelElementDelta delta,
			boolean addBuildpathChange) {
		ModelManager manager = ModelManager.getModelManager();
		DeltaProcessingState state = manager.deltaState;
		if (state.findProject(this.project.getElementName()) == null)
			// project doesn't exist yet (we're in an IWorkspaceRunnable)
			// no need to create a delta here and no need to index (see
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=133334)
			// the delta processor will create an ADDED project delta, and index
			// the project
			return NO_DELTA;

		DeltaProcessor deltaProcessor = state.getDeltaProcessor();
		IBuildpathEntry[] newResolvedBuildpath = null;
		int result = NO_DELTA;
		try {
			PerProjectInfo perProjectInfo = this.project.getPerProjectInfo();

			// get new info
			this.project.resolveBuildpath(perProjectInfo,
					false/*
							 * don't use previous session values
							 */, addBuildpathChange);
			IBuildpathEntry[] newRawBuildpath;

			// use synchronized block to ensure consistency
			synchronized (perProjectInfo) {
				newRawBuildpath = perProjectInfo.rawBuildpath;
				newResolvedBuildpath = perProjectInfo.getResolvedBuildpath();
			}

			if (newResolvedBuildpath == null) {
				// another thread reset the resolved buildpath, use a temporary
				// PerProjectInfo
				PerProjectInfo temporaryInfo = this.project.newTemporaryInfo();
				this.project.resolveBuildpath(temporaryInfo,
						false/*
								 * don't use previous session values
								 */, addBuildpathChange);
				newRawBuildpath = temporaryInfo.rawBuildpath;
				newResolvedBuildpath = temporaryInfo.getResolvedBuildpath();
			}

			// check if raw buildpath has changed
			if (this.oldRawBuildpath != null
					&& !ScriptProject.areBuildpathsEqual(this.oldRawBuildpath,
							newRawBuildpath)) {
				delta.changed(this.project,
						IModelElementDelta.F_BUILDPATH_CHANGED);
				result |= HAS_DELTA;

				// reset containers that are no longer on the buildpath
				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=139446)
				for (int i = 0, length = this.oldRawBuildpath.length; i < length; i++) {
					IBuildpathEntry entry = this.oldRawBuildpath[i];
					if (entry.getEntryKind() == IBuildpathEntry.BPE_CONTAINER) {
						if (buildpathContains(newRawBuildpath, entry) == -1)
							manager.containerPut(this.project, entry.getPath(),
									null);
					}
				}
			}

			// if no changes to resolved buildpath, nothing more to do
			if (this.oldResolvedBuildpath != null
					&& ScriptProject.areBuildpathsEqual(
							this.oldResolvedBuildpath, newResolvedBuildpath))
				return result;

			// close cached info
			this.project.close();

			// TODO: check is this is relevant here
			// ensure caches of dependent projects are reset as well (see
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=207890)
			// deltaProcessor.projectCachesToReset.add(this.project);
		} catch (ModelException e) {
			if (DeltaProcessor.VERBOSE) {
				e.printStackTrace();
			}
			// project no longer exist
			return result;
		}

		if (this.oldResolvedBuildpath == null)
			return result;

		delta.changed(this.project,
				IModelElementDelta.F_RESOLVED_BUILDPATH_CHANGED);
		result |= HAS_DELTA;

		state.addForRefresh(this.project);
		// ensure external jars are refreshed for this project (see
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=212769 )

		Map<IPath, IProjectFragment> removedRoots = null;
		IProjectFragment[] roots = null;
		Map<IScriptProject, IProjectFragment[]> allOldRoots;
		if ((allOldRoots = deltaProcessor.oldRoots) != null) {
			roots = allOldRoots.get(this.project);
		}
		if (roots != null) {
			removedRoots = new HashMap<>();
			for (int i = 0; i < roots.length; i++) {
				IProjectFragment root = roots[i];
				removedRoots.put(root.getPath(), root);
			}
		}

		int newLength = newResolvedBuildpath.length;
		int oldLength = this.oldResolvedBuildpath.length;
		for (int i = 0; i < oldLength; i++) {
			int index = buildpathContains(newResolvedBuildpath,
					this.oldResolvedBuildpath[i]);
			if (index == -1) {
				// remote project changes
				int entryKind = this.oldResolvedBuildpath[i].getEntryKind();
				if (entryKind == IBuildpathEntry.BPE_PROJECT) {
					result |= HAS_PROJECT_CHANGE;
					continue;
				}
				if (entryKind == IBuildpathEntry.BPE_LIBRARY) {
					result |= HAS_LIBRARY_CHANGE;
				}

				IProjectFragment[] pkgFragmentRoots = null;
				if (removedRoots != null) {
					IProjectFragment oldRoot = removedRoots
							.get(this.oldResolvedBuildpath[i].getPath());
					if (oldRoot != null) { // use old root if any (could be
						// none
						// if entry wasn't bound)
						pkgFragmentRoots = new IProjectFragment[] { oldRoot };
					}
				}
				if (pkgFragmentRoots == null) {
					try {
						List<IProjectFragment> accumulatedRoots = new ArrayList<>();
						HashSet<String> rootIDs = new HashSet<>(5);
						rootIDs.add(this.project.rootID());
						this.project.computeProjectFragments(
								this.oldResolvedBuildpath[i], accumulatedRoots,
								rootIDs, null, // inside original project
								false, // don't check existence
								false, // don't retrieve exported roots
								null); /* no reverse map */
						pkgFragmentRoots = accumulatedRoots.toArray(
								new IProjectFragment[accumulatedRoots.size()]);
					} catch (ModelException e) {
						pkgFragmentRoots = new IProjectFragment[] {};
					}
				}
				addBuildpathDeltas(delta, pkgFragmentRoots,
						IModelElementDelta.F_REMOVED_FROM_BUILDPATH);
			} else {
				// remote project changes
				if (this.oldResolvedBuildpath[i]
						.getEntryKind() == IBuildpathEntry.BPE_PROJECT) {
					result |= HAS_PROJECT_CHANGE;
					continue;
				}
				if (index != i) { // reordering of the buildpath
					addBuildpathDeltas(delta,
							this.project.computeProjectFragments(
									this.oldResolvedBuildpath[i]),
							IModelElementDelta.F_REORDER);
				}
				// TODO (alex) check source attachment
			}
		}

		for (int i = 0; i < newLength; i++) {
			int index = buildpathContains(this.oldResolvedBuildpath,
					newResolvedBuildpath[i]);
			if (index == -1) {
				// remote project changes
				int entryKind = newResolvedBuildpath[i].getEntryKind();
				if (entryKind == IBuildpathEntry.BPE_PROJECT) {
					result |= HAS_PROJECT_CHANGE;
					continue;
				}
				if (entryKind == IBuildpathEntry.BPE_LIBRARY) {
					result |= HAS_LIBRARY_CHANGE;
				}
				addBuildpathDeltas(delta,
						this.project.computeProjectFragments(
								newResolvedBuildpath[i]),
						IModelElementDelta.F_ADDED_TO_BUILDPATH);
			} // buildpath reordering has already been generated in previous
				// loop
		}

		return result;
	}

	@Override
	public int hashCode() {
		return this.project.hashCode();
	}

	/*
	 * Request the indexing of entries that have been added, and remove the
	 * index for removed entries.
	 */
	public void requestIndexing() {
		IBuildpathEntry[] newResolvedBuildpath = null;
		try {
			newResolvedBuildpath = this.project.getResolvedBuildpath();
		} catch (ModelException e) {
			// project doesn't exist
			return;
		}

		ModelManager manager = ModelManager.getModelManager();
		IndexManager indexManager = manager.indexManager;
		if (indexManager == null)
			return;
		DeltaProcessingState state = manager.deltaState;

		int newLength = newResolvedBuildpath.length;
		int oldLength = this.oldResolvedBuildpath == null ? 0
				: this.oldResolvedBuildpath.length;
		for (int i = 0; i < oldLength; i++) {
			int index = buildpathContains(newResolvedBuildpath,
					this.oldResolvedBuildpath[i]);
			if (index == -1) {
				// remote projects are not indexed in this project
				if (this.oldResolvedBuildpath[i]
						.getEntryKind() == IBuildpathEntry.BPE_PROJECT) {
					continue;
				}

				// Remove the source files from the index for a source folder
				// For a lib folder or a .zip file, remove the corresponding
				// index if not shared.
				IBuildpathEntry oldEntry = this.oldResolvedBuildpath[i];
				final IPath path = oldEntry.getPath();
				int changeKind = this.oldResolvedBuildpath[i].getEntryKind();
				switch (changeKind) {
				case IBuildpathEntry.BPE_SOURCE:
					char[][] inclusionPatterns = ((BuildpathEntry) oldEntry)
							.fullInclusionPatternChars();
					char[][] exclusionPatterns = ((BuildpathEntry) oldEntry)
							.fullExclusionPatternChars();
					indexManager.removeSourceFolderFromIndex(this.project, path,
							inclusionPatterns, exclusionPatterns);
					ProjectIndexerManager.removeProjectFragment(project, path);
					break;
				case IBuildpathEntry.BPE_LIBRARY:
					if (state.otherRoots.get(path) == null) { // if root was
						// not
						// shared
						indexManager.discardJobs(path.toString());
						indexManager.removeIndex(path);
						ProjectIndexerManager.removeLibrary(project, path);
					}
					break;
				}
			}
		}

		for (int i = 0; i < newLength; i++) {
			int index = buildpathContains(this.oldResolvedBuildpath,
					newResolvedBuildpath[i]);
			if (index == -1 || newResolvedBuildpath[i]
					.getEntryKind() == IBuildpathEntry.BPE_LIBRARY) {
				// remote projects are not indexed in this project
				if (newResolvedBuildpath[i]
						.getEntryKind() == IBuildpathEntry.BPE_PROJECT) {
					continue;
				}

				// Request indexing
				int entryKind = newResolvedBuildpath[i].getEntryKind();
				switch (entryKind) {
				case IBuildpathEntry.BPE_LIBRARY:
					boolean pathHasChanged = true;
					IPath newPath = newResolvedBuildpath[i].getPath();
					for (int j = 0; j < oldLength; j++) {
						IBuildpathEntry oldEntry = this.oldResolvedBuildpath[j];
						if (oldEntry.getPath().equals(newPath)) {
							pathHasChanged = false;
							break;
						}
					}
					if (pathHasChanged) {
						// IBuildpathEntry entry = newResolvedBuildpath[i];
						// char[][] inclusionPatterns = ((BuildpathEntry) entry)
						// .fullInclusionPatternChars();
						// char[][] exclusionPatterns = ((BuildpathEntry) entry)
						// .fullExclusionPatternChars();
						ProjectIndexerManager.indexLibrary(project, newPath);
					}
					break;
				case IBuildpathEntry.BPE_SOURCE:
					IBuildpathEntry entry = newResolvedBuildpath[i];
					IPath path = entry.getPath();
					// char[][] inclusionPatterns = ((BuildpathEntry) entry)
					// .fullInclusionPatternChars();
					// char[][] exclusionPatterns = ((BuildpathEntry) entry)
					// .fullExclusionPatternChars();
					ProjectIndexerManager.indexProjectFragment(project, path);
					break;
				}
			}
		}
	}

	@Override
	public String toString() {
		return "BuildpathChange: " + this.project.getElementName(); //$NON-NLS-1$
	}
}
