/*******************************************************************************
 * Copyright (c) 2016-2017 Red Hat 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:
 *     Mickael Istria (Red Hat Inc.) - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.internal.resources;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.internal.utils.FileUtil;
import org.eclipse.core.internal.utils.Messages;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.osgi.util.NLS;

public class CheckMissingNaturesListener implements IResourceChangeListener, IPreferenceChangeListener {

	public static final String MARKER_TYPE = ResourcesPlugin.getPlugin().getBundle().getSymbolicName() + ".unknownNature"; //$NON-NLS-1$
	public static final String NATURE_ID_ATTRIBUTE = "natureId"; //$NON-NLS-1$

	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		if (event.getDelta() == null) {
			return;
		}
		try {
			final Set<IProject> modifiedProjects = new HashSet<>();
			event.getDelta().accept(delta -> {
				if (delta.getResource() != null && delta.getResource().getType() == IResource.PROJECT && (delta.getKind() == IResourceDelta.ADDED || delta.getKind() == IResourceDelta.CHANGED)) {
					modifiedProjects.add((IProject) delta.getResource());
				}
				return delta.getResource() == null || delta.getResource().getType() == IResource.ROOT;
			});
			updateMarkers(modifiedProjects);
		} catch (CoreException e) {
			ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, ResourcesPlugin.getPlugin().getBundle().getSymbolicName(), e.getMessage(), e));
		}
	}

	int getMissingNatureSeverity(final IProject project) {
		int severity = PreferenceInitializer.PREF_MISSING_NATURE_MARKER_SEVERITY_DEFAULT;
		IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ResourcesPlugin.PI_RESOURCES);
		if (node != null) {
			severity = node.getInt(ResourcesPlugin.PREF_MISSING_NATURE_MARKER_SEVERITY, PreferenceInitializer.PREF_MISSING_NATURE_MARKER_SEVERITY_DEFAULT);
		}
		return severity;
	}

	@Override
	public void preferenceChange(PreferenceChangeEvent event) {
		if (ResourcesPlugin.PREF_MISSING_NATURE_MARKER_SEVERITY.equals(event.getKey())) {
			final int newSeverity = event.getNewValue() != null ? Integer.parseInt((String) event.getNewValue()) : PreferenceInitializer.PREF_MISSING_NATURE_MARKER_SEVERITY_DEFAULT;
			final int oldSeverity = event.getOldValue() != null ? Integer.parseInt((String) event.getOldValue()) : PreferenceInitializer.PREF_MISSING_NATURE_MARKER_SEVERITY_DEFAULT;
			if (newSeverity < 0) {
				removeAllMarkers(ResourcesPlugin.getWorkspace().getRoot());
			} else if (oldSeverity < 0 && newSeverity >= 0) {
				updateMarkers(Arrays.asList(ResourcesPlugin.getWorkspace().getRoot().getProjects()));
			} else {
				updateExistingMarkersSeverity(ResourcesPlugin.getWorkspace().getRoot(), newSeverity);
			}
		}
	}

	private void removeAllMarkers(IContainer workspaceRootOrProject) {
		final Collection<IMarker> markers = getRelatedMarkers(workspaceRootOrProject);
		if (markers.isEmpty()) {
			return;
		}
		WorkspaceJob job = new WorkspaceJob(Messages.updateUnknownNatureMarkers) {
			@Override
			public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
				for (IMarker marker : markers) {
					if (marker.exists() && marker.getResource().isAccessible()) {
						marker.delete();
					}
				}
				return Status.OK_STATUS;
			}

			@Override
			public boolean belongsTo(Object family) {
				return super.belongsTo(family) || MARKER_TYPE.equals(family);
			}
		};
		job.setUser(false);
		job.setSystem(true);
		job.setPriority(Job.DECORATE);
		job.setRule(workspaceRootOrProject);
		job.schedule();
	}

	private void updateExistingMarkersSeverity(IContainer workspaceRootOrProject, int newSeverity) {
		final Collection<IMarker> markers = getRelatedMarkers(workspaceRootOrProject);
		if (markers.isEmpty()) {
			return;
		}
		WorkspaceJob job = new WorkspaceJob(Messages.updateUnknownNatureMarkers) {
			@Override
			public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
				for (IMarker marker : markers) {
					if (marker.exists() && marker.getResource().isAccessible()) {
						marker.setAttribute(IMarker.SEVERITY, newSeverity);
					}
				}
				return Status.OK_STATUS;
			}

			@Override
			public boolean belongsTo(Object family) {
				return super.belongsTo(family) || MARKER_TYPE.equals(family);
			}
		};
		job.setUser(false);
		job.setSystem(true);
		job.setPriority(Job.DECORATE);
		job.setRule(workspaceRootOrProject);
		job.schedule();
	}

	private void updateMarkers(Collection<IProject> projects) {
		for (IProject project : projects) {
			if (!project.isAccessible()) {
				continue;
			}
			int severity = getMissingNatureSeverity(project);
			try {
				if (severity < 0) {
					removeAllMarkers(project);
					continue;
				}

				final Set<String> missingNatures = new HashSet<>();
				for (String natureId : project.getDescription().getNatureIds()) {
					if (project.getWorkspace().getNatureDescriptor(natureId) == null) {
						missingNatures.add(natureId);
					}
				}

				final Set<IMarker> toRemove = new HashSet<>();
				for (IMarker existingMarker : getRelatedProjectMarkers(project)) {
					String markerNature = existingMarker.getAttribute(NATURE_ID_ATTRIBUTE, ""); //$NON-NLS-1$
					if (!missingNatures.contains(markerNature)) {
						toRemove.add(existingMarker);
					} else {
						// no need to create a new marker
						missingNatures.remove(markerNature);
					}
				}

				if (!toRemove.isEmpty() || !missingNatures.isEmpty()) {
					WorkspaceJob workspaceJob = new WorkspaceJob(Messages.updateUnknownNatureMarkers) {
						@Override
						public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
							for (IMarker marker : toRemove) {
								marker.delete();
							}
							IResource targetResource = project.getFile(IProjectDescription.DESCRIPTION_FILE_NAME);
							if (!targetResource.isAccessible()) {
								targetResource = project;
							}
							for (String natureId : missingNatures) {
								IMarker marker = targetResource.createMarker(MARKER_TYPE);
								marker.setAttribute(IMarker.SEVERITY, getMissingNatureSeverity(project));
								marker.setAttribute(IMarker.MESSAGE, NLS.bind(Messages.natures_missingNature, natureId));
								marker.setAttribute(NATURE_ID_ATTRIBUTE, natureId);
								if (targetResource.getType() == IResource.FILE) {
									updateRange(marker, natureId, (IFile) targetResource);
								}
							}
							return Status.OK_STATUS;
						}

						@Override
						public boolean belongsTo(Object family) {
							return super.belongsTo(family) || MARKER_TYPE.equals(family);
						}
					};
					workspaceJob.setRule(project);
					workspaceJob.setUser(false);
					workspaceJob.setSystem(true);
					workspaceJob.setPriority(Job.DECORATE);
					workspaceJob.schedule();
				}
			} catch (CoreException e) {
				ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, e.getMessage(), e));
			}
		}
	}

	protected void updateRange(IMarker marker, String natureId, IFile file) {
		if (!file.isAccessible()) {
			return;
		}
		Pattern pattern = Pattern.compile(".*<" + IModelObjectConstants.NATURE + ">\\s*(" + natureId.replace(".", "\\.") + ")\\s*</" + IModelObjectConstants.NATURE + ">.*", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
				Pattern.DOTALL);
		try (InputStream input = file.getContents(); ByteArrayOutputStream output = new ByteArrayOutputStream();) {
			FileUtil.transferStreams(input, output, file.getLocation().toString(), new NullProgressMonitor());
			String content = output.toString();
			Matcher matcher = pattern.matcher(content);
			if (matcher.matches() && matcher.groupCount() > 0) {
				marker.setAttribute(IMarker.CHAR_START, matcher.start(1));
				marker.setAttribute(IMarker.CHAR_END, matcher.end(1) - 1);
			}
		} catch (IOException e) {
			ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, e.getMessage(), e));
		} catch (CoreException e) {
			ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, e.getMessage(), e));
		}
	}

	protected Collection<IMarker> getRelatedMarkers(IContainer rootOrProject) {
		switch (rootOrProject.getType()) {
			case IResource.ROOT :
				return getRelatedRootMarkers((IWorkspaceRoot) rootOrProject);
			case IResource.PROJECT :
				return getRelatedProjectMarkers((IProject) rootOrProject);
		}
		return Collections.emptyList();
	}

	protected Collection<IMarker> getRelatedRootMarkers(IWorkspaceRoot root) {
		if (!root.isAccessible()) {
			return Collections.emptyList();
		}
		Set<IMarker> res = new HashSet<>();
		for (IProject project : root.getProjects()) {
			res.addAll(getRelatedProjectMarkers(project));
		}
		return res;
	}

	protected Collection<IMarker> getRelatedProjectMarkers(IProject project) {
		if (!project.isAccessible()) {
			return Collections.emptyList();
		}
		try {
			return Arrays.asList(project.findMarkers(MARKER_TYPE, true, IResource.DEPTH_ONE));
		} catch (CoreException e) {
			ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, e.getMessage(), e));
			return Collections.emptyList();
		}
	}

}
