/*******************************************************************************
 * Copyright (c) 2010, 2017 xored software, Inc. 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:
 *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
 *******************************************************************************/
package org.eclipse.dltk.internal.core.builder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
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.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.builder.IRenameChange;
import org.eclipse.dltk.utils.TextUtils;

public class IncrementalProjectChange extends AbstractBuildChange
		implements IResourceDeltaVisitor {

	private final IResourceDelta delta;

	public IncrementalProjectChange(IResourceDelta delta, IProject project,
			IProgressMonitor monitor) {
		super(project, monitor);
		this.delta = delta;
	}

	@Override
	public IResourceDelta getResourceDelta() {
		return delta;
	}

	@SuppressWarnings("unchecked")
	private final List<IPath>[] deletes = new List[9];

	@Override
	public List<IPath> getDeletes(int options) throws CoreException {
		validateFlags(options, NO_RENAMES);
		loadData();
		if (deletes[options] == null) {
			final List<IPath> paths = new ArrayList<>();
			if (projectDeletes != null) {
				paths.addAll(projectDeletes);
			}
			if (wantRenames(options) && projectRenames != null) {
				paths.addAll(projectRenames.values());
			}
			deletes[options] = unmodifiableList(paths);
		}
		return deletes[options];
	}

	@Override
	public List<IRenameChange> getRenames() throws CoreException {
		loadData();
		if (projectRenames != null) {
			return projectRenames.getRenames();
		} else {
			return Collections.emptyList();
		}
	}

	@SuppressWarnings("unchecked")
	private final List<IFile>[] resources = new List[16];

	@Override
	public List<IFile> getResources(int options) throws CoreException {
		options = validateFlags(options, ALL | NO_RENAMES | ADDED | CHANGED);
		if ((options & (ADDED | CHANGED | NO_RENAMES)) == (CHANGED
				| NO_RENAMES)) {
			throw new IllegalArgumentException();
		}
		loadData();
		if (resources[options] == null) {
			final List<IFile> files = new ArrayList<>();
			if (checkFlag(options, ADDED)) {
				if (projectAdditions != null) {
					files.addAll(projectAdditions
							.getResources(checkFlag(options, ALL)));
				}
				if (wantRenames(options) && projectRenames != null) {
					files.addAll(projectRenames
							.getResources(checkFlag(options, ALL)));
				}
			}
			if (checkFlag(options, CHANGED)) {
				if (projectChanges != null) {
					files.addAll(projectChanges
							.getResources(checkFlag(options, ALL)));
				}
			}
			resources[options] = unmodifiableList(files);
		}
		return resources[options];
	}

	@SuppressWarnings("unchecked")
	private final List<ISourceModule>[] modules = new List[4];

	@Override
	public List<ISourceModule> getSourceModules(int options)
			throws CoreException {
		options = validateFlags(options, ADDED | CHANGED);
		loadData();
		if (modules[options] == null) {
			final List<ISourceModule> m = new ArrayList<>();
			if (checkFlag(options, ADDED)) {
				if (projectAdditions != null) {
					m.addAll(projectAdditions.getSourceModules());
				}
				if (projectRenames != null) {
					m.addAll(projectRenames.getSourceModules());
				}
			}
			if (checkFlag(options, CHANGED)) {
				if (projectChanges != null) {
					m.addAll(projectChanges.getSourceModules());
				}
			}
			modules[options] = unmodifiableList(m);
		}
		return modules[options];
	}

	private boolean loaded = false;

	protected final void loadData() throws CoreException {
		if (!loaded) {
			loaded = true;
			delta.accept(this);
		}
	}

	@SuppressWarnings("serial")
	abstract class AbstractChangeSet<T> extends HashMap<IFile, T> {
		List<ISourceModule> modules = null;
		Set<IFile> realResources = null;

		public Collection<? extends IFile> getAll() {
			return keySet();
		}

		void resetDerivedContent() {
			modules = null;
			realResources = null;
		}

		List<ISourceModule> getSourceModules() {
			if (modules == null) {
				detectSourceModules();
			}
			return modules;
		}

		Collection<IFile> getResources() {
			if (realResources == null) {
				detectSourceModules();
			}
			return realResources;
		}

		Collection<? extends IFile> getResources(boolean all) {
			return all ? getAll() : getResources();
		}

		private final void detectSourceModules() {
			final List<ISourceModule> m = new ArrayList<>();
			final Set<IFile> rr = new HashSet<>();
			locateSourceModules(this.keySet(), m, rr);
			this.modules = unmodifiableList(m);
			this.realResources = unmodifiableSet(rr);
		}
	}

	@SuppressWarnings("serial")
	class ChangeSet extends AbstractChangeSet<Object> {
		void add(IFile file) {
			put(file, Boolean.TRUE);
		}

		@Override
		public String toString() {
			return keySet().toString();
		}
	}

	@SuppressWarnings("serial")
	class RenameChangeSet extends AbstractChangeSet<IPath> {
		List<IRenameChange> renames = null;

		@Override
		void resetDerivedContent() {
			super.resetDerivedContent();
			renames = null;
		}

		List<IRenameChange> getRenames() {
			if (renames == null) {
				final List<IRenameChange> r = new ArrayList<>();
				for (Map.Entry<IFile, IPath> entry : entrySet()) {
					r.add(new RenameChange(entry.getValue(), entry.getKey()));
				}
				this.renames = unmodifiableList(r);
			}
			return renames;
		}

	}

	private ChangeSet projectAdditions = null;
	private ChangeSet projectChanges = null;
	/**
	 * Project-relative paths of the deleted files.
	 */
	private List<IPath> projectDeletes = null;
	private RenameChangeSet projectRenames = null;

	protected void resetDerivedProjectChanges() {
		if (projectAdditions != null) {
			projectAdditions.resetDerivedContent();
		}
		if (projectChanges != null) {
			projectChanges.resetDerivedContent();
		}
		if (projectRenames != null) {
			projectRenames.resetDerivedContent();
		}
		Arrays.fill(deletes, null);
		Arrays.fill(resources, null);
		Arrays.fill(modules, null);
	}

	protected boolean addChangedResource(IFile file) throws CoreException {
		Assert.isLegal(project.equals(file.getProject()));
		loadData();
		if (projectAdditions != null && projectAdditions.containsKey(file)) {
			return false;
		}
		if (projectChanges == null) {
			projectChanges = new ChangeSet();
		}
		if (!projectChanges.containsKey(file)) {
			projectChanges.add(file);
			resetDerivedProjectChanges();
			return true;
		}
		return false;
	}

	@Override
	public boolean visit(IResourceDelta delta) throws CoreException {
		checkCanceled();
		final IResource resource = delta.getResource();
		// System.out.println(resource);
		if (resource.getType() == IResource.FOLDER) {
			this.monitor.subTask(Messages.ScriptBuilder_scanningProjectFolder
					+ resource.getProjectRelativePath().toString());
		}
		if (resource.getType() == IResource.FILE) {
			switch (delta.getKind()) {
			case IResourceDelta.ADDED:
				if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0) {
					if (projectRenames == null) {
						projectRenames = new RenameChangeSet();
					}
					projectRenames.put((IFile) resource,
							delta.getMovedFromPath().removeFirstSegments(1));
				} else {
					if (projectAdditions == null) {
						projectAdditions = new ChangeSet();
					}
					projectAdditions.add((IFile) resource);
				}
				break;
			case IResourceDelta.CHANGED:
				if ((delta.getFlags() & (IResourceDelta.CONTENT
						| IResourceDelta.ENCODING)) != 0) {
					if (projectChanges == null) {
						projectChanges = new ChangeSet();
					}
					projectChanges.add((IFile) resource);
				}
				break;
			case IResourceDelta.REMOVED:
				if ((delta.getFlags() & IResourceDelta.MOVED_TO) == 0) {
					if (projectDeletes == null) {
						projectDeletes = new ArrayList<>();
					}
					projectDeletes.add(delta.getProjectRelativePath());
				}
				break;
			}
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		try {
			loadData();
		} catch (CoreException e) {
			return e.toString();
		}
		final List<String> lines = new ArrayList<>();
		if (projectAdditions != null) {
			lines.add("additions=" + projectAdditions.toString());
		}
		if (projectChanges != null) {
			lines.add("changes=" + projectChanges.toString());
		}
		if (projectDeletes != null) {
			lines.add("deletes=" + projectDeletes);
		}
		return TextUtils.join(lines, "\n");
	}

	protected Set<IPath> getAddedPaths() throws CoreException {
		loadData();
		final Set<IPath> paths = new HashSet<>();
		if (projectAdditions != null) {
			for (IFile file : projectAdditions.getAll()) {
				paths.add(file.getFullPath());
			}
		}
		if (projectRenames != null) {
			for (IRenameChange rename : projectRenames.getRenames()) {
				paths.add(rename.getTarget().getFullPath());
			}
		}
		return paths;
	}

	/**
	 * Returns full paths of the deleted files.
	 */
	protected Collection<IPath> getDeletedPaths() throws CoreException {
		loadData();
		final Set<IPath> paths = new HashSet<>();
		if (projectDeletes != null) {
			final IPath projectPath = project.getFullPath();
			for (IPath path : projectDeletes) {
				paths.add(projectPath.append(path));
			}
		}
		if (projectRenames != null) {
			final IPath projectPath = project.getFullPath();
			for (IRenameChange rename : projectRenames.getRenames()) {
				paths.add(projectPath.append(rename.getSource()));
			}
		}
		return paths;
	}

	protected Set<IPath> getChangedPaths() throws CoreException {
		loadData();
		final Set<IPath> paths = new HashSet<>();
		if (projectAdditions != null) {
			for (IFile file : projectAdditions.getAll()) {
				paths.add(file.getFullPath());
			}
		}
		if (projectChanges != null) {
			for (IFile file : projectChanges.getAll()) {
				paths.add(file.getFullPath());
			}
		}
		if (projectDeletes != null) {
			final IPath projectPath = project.getFullPath();
			for (IPath path : projectDeletes) {
				paths.add(projectPath.append(path));
			}
		}
		if (projectRenames != null) {
			final IPath projectPath = project.getFullPath();
			for (IRenameChange rename : projectRenames.getRenames()) {
				paths.add(projectPath.append(rename.getSource()));
				paths.add(rename.getTarget().getFullPath());
			}
		}
		return paths;
	}

}
