/*******************************************************************************
 * Copyright (c) 2017,2019 Willink Transformations and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   E.D.Willink - Initial API and implementation based on org.eclipse.xtext.builder.nature.XtextNature
 *******************************************************************************/
package org.eclipse.ocl.xtext.base.ui.builder;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
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.resources.IResourceVisitor;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.emf.ecore.EValidator;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.xtext.base.ui.BaseUIActivator;
import org.eclipse.ocl.xtext.base.ui.builder.AbstractValidatingBuilder.BuildType;

/**
 * An AbstractBuildSelector performs the selection of files to be built from within a project.
 * Selection is based on inclusion/exclusion of file-extensions/file-paths.
 */
public abstract class AbstractBuildSelector implements IResourceVisitor, IResourceDeltaVisitor
{
	protected final @NonNull IProject project;
	protected final @NonNull BuildType buildType;
	private final @NonNull IProgressMonitor monitor;
	private final @NonNull Map<@NonNull String, @Nullable Boolean> extension2included = new HashMap<>();
	private final char[][] exclusionPatterns;
	private final char[][] inclusionPatterns;

	private final @NonNull Set<@NonNull IFile> removedFiles = new HashSet<>();
	private final @NonNull Set<@NonNull ValidationEntry> selectedEntries = new HashSet<>();

	protected AbstractBuildSelector(@NonNull IProject project, @NonNull BuildType buildType, @Nullable Map<String, String> args, @NonNull IProgressMonitor monitor) {
		this.project = project;
		this.buildType = buildType;
		this.monitor = monitor;
		String[] disabledPathArray = null;
		String[] enabledPathArray = null;
		if (args != null) {
			String includedExtensions = args.get("enabledExtensions");
			if (includedExtensions != null) {
				for (@NonNull String includedExtension : includedExtensions.split(",")) {
					@SuppressWarnings("unused") Boolean oldIncludes = extension2included.put(includedExtension, Boolean.TRUE);
					// assert oldIncludes != null; double true is not an issue
				}
			}
			String excludedExtensions = args.get("disabledExtensions");
			if (excludedExtensions != null) {
				for (@NonNull String excludedExtension : excludedExtensions.split(",")) {
					@SuppressWarnings("unused") Boolean oldExcludes = extension2included.put(excludedExtension, Boolean.FALSE);
					// assert oldExcludes != null; double false / conflicting false is not really an issue
				}
			}
			String enabledPaths = args.get("enabledPaths");
			if (enabledPaths != null) {
				enabledPathArray = enabledPaths.split(",");
			}
			String disabledPaths = args.get("disabledPaths");
			if (disabledPaths != null) {
				disabledPathArray = disabledPaths.split(",");
			}
		}
		if (enabledPathArray != null) {
			inclusionPatterns = new char[enabledPathArray.length][];
			for (int i = 0; i < enabledPathArray.length; i++) {
				String enabledPath = enabledPathArray[i];
				inclusionPatterns[i] = (enabledPath.length() > 0 ? enabledPath : "**").toCharArray();
			}
		}
		else {
			inclusionPatterns = null;
		}
		if (disabledPathArray != null) {
			exclusionPatterns = new char[disabledPathArray.length][];
			for (int i = 0; i < disabledPathArray.length; i++) {
				String disabledPath = disabledPathArray[i];
				exclusionPatterns[i] = (disabledPath.length() > 0 ? disabledPath : "**").toCharArray();
			}
		}
		else {
			exclusionPatterns = null;
		}
	}

	public void buildResources() {
		MultiValidationJob multiValidationJob = BaseUIActivator.getMultiValidationJob();
		if (multiValidationJob != null) {
			multiValidationJob.addValidations(selectedEntries);
		}
	}

	protected @NonNull ValidationEntry createValidationEntry(@NonNull IFile iFile) {
		return new ValidationEntry(iFile, getMarkerId(iFile));
	}

	/**
	 * Return the appropriate Problem Marked Id for the results of validating iFile.
	 * Defaults to "org.eclipse.emf.ecore.diagnostic". Subclasses should override.
	 */
	@SuppressWarnings("null")
	protected @NonNull String getMarkerId(@NonNull IFile iFile) {
		return EValidator.MARKER;
	}

	public @Nullable Boolean isSelected(@NonNull IResource resource) {
		if (resource instanceof IFile) {
			String fileExtension = resource.getFileExtension();
			if (extension2included.get(fileExtension) != Boolean.TRUE) {
				return Boolean.FALSE;
			}
			String filePath = resource.getProjectRelativePath().toString();
			char[] path = filePath.toCharArray();
			boolean isExcluded = AbstractValidatingBuilder.isExcluded(path, inclusionPatterns, exclusionPatterns, false);
			//				System.out.println(filePath + " isExcluded " + isExcluded);
			return isExcluded ? Boolean.FALSE : Boolean.TRUE;
		}
		else if (resource instanceof IFolder) {
			// FIXME BUG 544734 this match doesn't work for non-trivial folder paths
		//	String filePath = resource.getProjectRelativePath().toString();
		//	char[] path = filePath.toCharArray();
		//	boolean isExcluded = AbstractValidatingBuilder.isExcluded(path, inclusionPatterns, exclusionPatterns, true);
			//				System.out.println(filePath + " isExcluded " + isExcluded);
			return /*isExcluded ? Boolean.FALSE :*/ null;
		}
		else {
			return null;
		}
	}

	public int selectResources(@Nullable IResourceDelta delta) throws CoreException {
		//			progress.subTask(selectingResourcesMessage);
		if (delta == null) {			// full
			project.accept(this, IResource.DEPTH_INFINITE, IResource.NONE);
		}
		else {							// auto / incremental
			delta.accept(this);
		}
		return selectedEntries.size();
	}

	@Override
	public boolean visit(IResource resource) throws CoreException {
		if (monitor.isCanceled())
			throw new OperationCanceledException();
		assert resource != null;
		//			System.out.println(NameUtil.debugSimpleName(this) + " visit " + resource);
		Boolean isSelected = isSelected(resource);
		if (isSelected == Boolean.TRUE) {
			IFile iFile = (IFile) resource;
			selectedEntries.add(createValidationEntry(iFile));
			return true;
		}
		else if (isSelected == null) {
			return true;
		}
		else {
			return false;
		}
	}

	@Override
	public boolean visit(IResourceDelta delta) throws CoreException {
		if (monitor.isCanceled())
			throw new OperationCanceledException();
		IResource resource = delta.getResource();
		if (resource instanceof IProject) {
			return (resource == project) && project.isOpen();
		}
		if (resource instanceof IContainer) {
			return true;
		}
		if (resource instanceof IStorage) {
			if (delta.getKind() == IResourceDelta.REMOVED) {
				//					System.out.println(NameUtil.debugSimpleName(this) + " remove " + resource);
				Boolean isSelected = isSelected(resource);
				if (isSelected == Boolean.TRUE) {
				//	IPath fullPath = ((IFile) resource).getFullPath();
				//	assert fullPath != null;
					removedFiles.add((IFile) resource);
					return true;
				}
				else if (isSelected == null) {
					return true;
				}
				else {
					return false;
				}
			} else if (delta.getKind() == IResourceDelta.ADDED || delta.getKind() == IResourceDelta.CHANGED) {
				//					System.out.println(NameUtil.debugSimpleName(this) + " update " + resource);
				Boolean isSelected = isSelected(resource);
				if (isSelected == Boolean.TRUE) {
					IFile iFile = (IFile) resource;
					selectedEntries.add(createValidationEntry(iFile));
					return true;
				}
				else if (isSelected == null) {
					return true;
				}
				else {
					return false;
				}
			}
		}
		return false;
	}

	public void deleteMarkers() {
		for (@NonNull ValidationEntry entry : selectedEntries) {
			try {
				entry.deleteMarkers();
			} catch (CoreException e) {
				// e.printStackTrace();  -- if deleteMarkers fails we probably don't want extra noise
			}
		}
	}

	protected int deleteRemovedResourceMarkers() {
		for (@NonNull IFile removedFile : removedFiles) {
			try {
				String markerId = getMarkerId(removedFile);
			//	if (AbstractValidatingBuilder.BUILDER.isActive()) {
			//		AbstractValidatingBuilder.BUILDER.println("Remove \"" + markerId + "\" markers from \"" + removedFile.getFullPath() + "\"");
			//	}
				removedFile.deleteMarkers(markerId, true, IResource.DEPTH_ZERO);
			} catch (CoreException e) {
			//	e.printStackTrace();
			}
		}
		return removedFiles.size();
	}
}