/*******************************************************************************
 *  Copyright (c) 2013, 2016 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.releng.internal.tools.pomversion;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.jar.JarFile;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.eclipse.releng.tools.RelEngPlugin;
import org.eclipse.ui.texteditor.MarkerUtilities;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


/**
 * Validates the content of the pom.xml.  Currently the only check is that the
 * version specified in pom.xml matches the bundle version.
 *
 */
public class PomVersionErrorReporter implements IResourceChangeListener, IEclipsePreferences.IPreferenceChangeListener {

	class PomResourceDeltaVisitor implements IResourceDeltaVisitor {

		@Override
		public boolean visit(IResourceDelta delta) {
			if (delta != null) {
				IResource resource = delta.getResource();
				switch(resource.getType()) {
				case IResource.PROJECT: {
					if(delta.getKind() == IResourceDelta.REMOVED) {
						return false;
					}
					IProject project = (IProject) resource;
					try {
						if(project.isAccessible() && (project.getDescription().hasNature("org.eclipse.pde.PluginNature") || project.getDescription().hasNature("org.eclipse.pde.FeatureNature"))) { //$NON-NLS-1$ //$NON-NLS-2$
							if((delta.getFlags() & IResourceDelta.OPEN) > 0) {
								validate(project);
								return false;
							}
							return true;
						}
					}
					catch(CoreException ce) {
						RelEngPlugin.log(ce);
					}
					return false;
				}
				case IResource.ROOT:
				case IResource.FOLDER: {
					return true;
				}
				case IResource.FILE: {
					switch(delta.getKind()) {
					case IResourceDelta.REMOVED: {
						//if manifest or feature removed, clean up markers
						if(resource.getProjectRelativePath().equals(FEATURE_PATH) || 
								resource.getProjectRelativePath().equals(MANIFEST_PATH)) {
							IProject p = resource.getProject();
							if(p.isAccessible()) {
								cleanMarkers(p);
							}
						}
						break;
					}
					case IResourceDelta.ADDED: {
						//if the POM, manifest or feature.xml has been added scan them
						if(resource.getProjectRelativePath().equals(FEATURE_PATH) ||
								resource.getProjectRelativePath().equals(MANIFEST_PATH) ||
								resource.getProjectRelativePath().equals(POM_PATH)) {
							validate(resource.getProject());
						}
						break;
					}
					case IResourceDelta.CHANGED: {
						//if the content has changed clean + scan
						if((delta.getFlags() & IResourceDelta.CONTENT) > 0) {
							if(resource.getProjectRelativePath().equals(FEATURE_PATH) || 
									resource.getProjectRelativePath().equals(MANIFEST_PATH) ||
									resource.getProjectRelativePath().equals(POM_PATH)) {
								validate(resource.getProject());
							}
						}
						break;
					}
					default: {
						break;
					}
					}
					return false;
				}
				}
			}				
			return false;
		}
	}

	/**
	 * XML parsing handler to check the POM version infos
	 */
	class PomVersionHandler extends DefaultHandler {
		private Version version;
		private Stack<String> elements = new Stack<>();
		private boolean checkVersion = false;
		private boolean isFeatureProject = false;
		private Locator locator;
		IFile pom = null;
		String severity = null;

		public PomVersionHandler(IFile file, Version bundleVersion, String pref) {
			this(file, bundleVersion, pref, false);
		}
		
		public PomVersionHandler(IFile file, Version version, String pref, boolean isFeatureProject) {
			pom = file;
			severity = pref;
			this.version = version;
			this.isFeatureProject = isFeatureProject;
		}

		@Override
		public void setDocumentLocator(Locator locator) {
			this.locator = locator;
		}

		@Override
		public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
			if (ELEMENT_VERSION.equals(qName)) {
				if (!elements.isEmpty() && ELEMENT_PROJECT.equals(elements.peek())) {
					checkVersion = true;
				}
			}
			elements.push(qName);
		}

		@Override
		public void endElement(String uri, String localName, String qName) throws SAXException {
			elements.pop();
		}

		@Override
		public void characters(char[] ch, int start, int length) throws SAXException {
			if (checkVersion) {
				checkVersion = false;

				try {
					// Remove the snapshot suffix
					String versionString = new String(ch, start, length);
					String origVer = versionString;
					int index = versionString.indexOf(SNAPSHOT_SUFFIX);
					if (index >= 0) {
						versionString = versionString.substring(0, index);
					}

					// Create corrected version (no qualifiers, add back snapshot suffix)
					Version bundleVersion2 = new Version(version.getMajor(), version.getMinor(), version.getMicro());
					String correctedVersion = bundleVersion2.toString();
					if (index >= 0) {
						correctedVersion = correctedVersion.concat(SNAPSHOT_SUFFIX);
					}

					// Check if the pom version is a valid OSGi version
					Version pomVersion = null;
					try {
						pomVersion = Version.parseVersion(versionString);
					} catch (IllegalArgumentException e){
						// Need to create a document to calculate the markers charstart and charend
						IDocument doc = createDocument(pom);
						int lineOffset = doc.getLineOffset(locator.getLineNumber() - 1); // locator lines start at 1
						int linLength = doc.getLineLength(locator.getLineNumber() - 1);
						String str = doc.get(lineOffset, linLength);
						index = str.indexOf(origVer);
						int charStart = lineOffset + index;
						int charEnd = charStart + origVer.length();
						
						String message = isFeatureProject ? Messages.PomVersionErrorReporter_pom_version_error_marker_message_feature : Messages.PomVersionErrorReporter_pom_version_error_marker_message;
						reportMarker(NLS.bind(message, versionString, bundleVersion2.toString()), 
								locator.getLineNumber(), 
								charStart, 
								charEnd, 
								correctedVersion,
								pom,
								severity);
					}

					if (pomVersion == null){
						return;
					}

					// Compare the versions
					Version pomVersion2 = new Version(pomVersion.getMajor(), pomVersion.getMinor(), pomVersion.getMicro());
					if (!bundleVersion2.equals(pomVersion2)) {
						// Need to create a document to calculate the markers charstart and charend
						IDocument doc = createDocument(pom);
						int lineOffset = doc.getLineOffset(locator.getLineNumber() - 1); // locator lines start at 1
						int linLength = doc.getLineLength(locator.getLineNumber() - 1);
						String str = doc.get(lineOffset, linLength);
						index = str.indexOf(origVer);
						int charStart = lineOffset + index;
						int charEnd = charStart + origVer.length();
						String message = isFeatureProject ? Messages.PomVersionErrorReporter_pom_version_error_marker_message_feature : Messages.PomVersionErrorReporter_pom_version_error_marker_message;
						reportMarker(NLS.bind(message, pomVersion2.toString(), bundleVersion2.toString()), 
								locator.getLineNumber(), 
								charStart, 
								charEnd, 
								correctedVersion,
								pom,
								severity);
					}
				} catch (IllegalArgumentException e) {
					// If the manifest version is broken, let PDE report the problem
				} catch (BadLocationException e) {
					RelEngPlugin.log(e);
				}
			}
		}
	}
	
	/**
	 * XML parsing handler to check the feature.xml version
	 */
	class FeatureVersionHandler extends DefaultHandler {
		private String featureVersion;

		public FeatureVersionHandler() {
		}

		@Override
		public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
			// The version is on the root element, check for the attribute then throw exception to exit early
			featureVersion = attributes.getValue("version"); //$NON-NLS-1$
			throw new OperationCanceledException();
		}

		/**
		 * Returns the string version value found in the feature.xml or <code>null</code>
		 * 
		 * @return string version from feature.xml or <code>null</code>
		 */
		public String getVersion() {
			return featureVersion;
		}

	}

	/**
	 * Project relative path to the pom.xml file.
	 */
	public static final IPath POM_PATH = new Path("pom.xml"); //$NON-NLS-1$

	/**
	 * Project relative path to the manifest file.
	 */
	public static final IPath MANIFEST_PATH = new Path(JarFile.MANIFEST_NAME);

	/**
	 * Version of the PomVersionErrorReporter. Needs to be incremented when the version check algorithm changes
	 * in a way that requires re-validation of the whole workspace.
	 */
	public static final int VERSION= 1;

	/**
	 * Project relative path to the feature.xml file.
	 */
	public static final IPath FEATURE_PATH = new Path("feature.xml"); //$NON-NLS-1$

	private static final String ELEMENT_PROJECT = "project"; //$NON-NLS-1$
	private static final String ELEMENT_VERSION = "version"; //$NON-NLS-1$
	private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT"; //$NON-NLS-1$


	/**
	 * Clean up all markers
	 * 
	 * @param project
	 */
	void cleanMarkers(IResource resource) {
		try {
			resource.deleteMarkers(IPomVersionConstants.PROBLEM_MARKER_TYPE, false, IResource.DEPTH_INFINITE);
		}
		catch(CoreException e) {
			RelEngPlugin.log(e);
		}
	}

	/**
	 * Validates the manifest or feature version against the version in the <code>pom.xml</code> file
	 * 
	 * @param project
	 * @param severity
	 */
	public void validate(IProject project) {
		if(project == null || !project.isAccessible()) {
			return;
		}
		// Clean up existing markers
		cleanMarkers(project);

		String severity = RelEngPlugin.getPlugin().getPreferenceStore().getString(IPomVersionConstants.POM_VERSION_ERROR_LEVEL);
		if (IPomVersionConstants.VALUE_IGNORE.equals(severity)) {
			return;
		}
		IFile pom = project.getFile(POM_PATH);
		if(!pom.exists()) {
			return;
		}

		IFile manifest = project.getFile(MANIFEST_PATH);
		if(manifest.exists()) {
			// Get the manifest version
			Version bundleVersion = Version.emptyVersion;
			try {
				Map<String, String> headers = new HashMap<>();
				ManifestElement.parseBundleManifest(manifest.getContents(), headers);
				String ver = headers.get(Constants.BUNDLE_VERSION);
				if(ver == null) {
					return;
				}
				bundleVersion = Version.parseVersion(ver);
			} catch (IOException e) {
				// Ignored, if there is a problem with the manifest, don't create a marker
				return;
			} catch (CoreException e){
				// Ignored, if there is a problem with the manifest, don't create a marker
				return;
			} catch (BundleException e) {
				// Ignored, if there is a problem with the manifest, don't create a marker
				return;
			} catch (IllegalArgumentException e){
				// Ignored, if there is a problem with the manifest, don't create a marker
				return;
			}
			// Compare it to the POM file version
			try {
				SAXParserFactory parserFactory = SAXParserFactory.newInstance();
				SAXParser parser = parserFactory.newSAXParser();
				PomVersionHandler handler = new PomVersionHandler(pom, bundleVersion, severity);
				parser.parse(pom.getContents(), handler);
			} catch (Exception e) {
				// Ignored, if there is a problem with the POM file don't create a marker
				return;
			}

		} else {
			IFile feature = project.getFile(FEATURE_PATH);
			if (feature.exists()){
				try {
					// Get the feature version
					Version featureVersion = Version.emptyVersion;
					SAXParserFactory parserFactory = SAXParserFactory.newInstance();
					SAXParser parser = parserFactory.newSAXParser();
					FeatureVersionHandler handler = new FeatureVersionHandler();
					try {
						parser.parse(feature.getContents(), handler);
					} catch (OperationCanceledException e){
						// Do nothing, used to avoid parsing the entire file
					}
					
					String version = handler.getVersion();
					if (version == null){
						// Ignored, if there is a problem with the feature, don't create a marker
						return;
					}
					featureVersion = Version.parseVersion(version);
					
					// Compare it to the POM file version
					PomVersionHandler pomHandler = new PomVersionHandler(pom, featureVersion, severity, true);
					parser.parse(pom.getContents(), pomHandler);
				} catch (Exception e) {
					// Ignored, if there is a problem with the POM file don't create a marker
					return;
				}
			}
		}
	}

	/**
	 * Creates a new POM version problem marker with the given attributes
	 * @param message the message for the marker
	 * @param lineNumber the line number of the problem
	 * @param charStart the starting character offset
	 * @param charEnd the ending character offset
	 * @param correctedVersion the correct version to be inserted
	 * @param pom the handle to the POM file
	 * @param severity the severity of the marker to create
	 */
	void reportMarker(String message, int lineNumber, int charStart, int charEnd, String correctedVersion, IFile pom, String severity) {
		try {
			HashMap<String, Object> attributes = new HashMap<>();
			attributes.put(IMarker.MESSAGE, message);
			if (severity.equals(IPomVersionConstants.VALUE_WARNING)){
				attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_WARNING));
			} else {
				attributes.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
			}
			if (lineNumber == -1) {
				lineNumber = 1;
			}
			attributes.put(IMarker.LINE_NUMBER, new Integer(lineNumber));
			attributes.put(IMarker.CHAR_START, new Integer(charStart));
			attributes.put(IMarker.CHAR_END, new Integer(charEnd));
			attributes.put(IPomVersionConstants.POM_CORRECT_VERSION, correctedVersion);
			MarkerUtilities.createMarker(pom, attributes, IPomVersionConstants.PROBLEM_MARKER_TYPE);
		} catch (CoreException e){
			RelEngPlugin.log(e);
		}
	}

	/**
	 * Creates a new {@link IDocument} for the given {@link IFile}. <code>null</code>
	 * is returned if the {@link IFile} does not exist or the {@link ITextFileBufferManager}
	 * cannot be acquired or there was an exception trying to create the {@link IDocument}.
	 * 
	 * @param file
	 * @return a new {@link IDocument} or <code>null</code>
	 */
	protected IDocument createDocument(IFile file) {
		if (!file.exists()) {
			return null;
		}
		ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
		if (manager == null) {
			return null;
		}
		try {
			manager.connect(file.getFullPath(), LocationKind.NORMALIZE, null);
			ITextFileBuffer textBuf = manager.getTextFileBuffer(file.getFullPath(), LocationKind.NORMALIZE);
			IDocument document = textBuf.getDocument();
			manager.disconnect(file.getFullPath(), LocationKind.NORMALIZE, null);
			return document;
		} catch (CoreException e) {
			RelEngPlugin.log(e);
		}
		return null;
	}

	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		IResourceDelta delta = event.getDelta();
		if(delta != null) {
			final PomResourceDeltaVisitor visitor = new PomResourceDeltaVisitor();
			try {
				delta.accept(visitor);
			} catch (CoreException e) {
				RelEngPlugin.log(e);
			}
		}
	}

	@Override
	public void preferenceChange(PreferenceChangeEvent event) {
		if(IPomVersionConstants.POM_VERSION_ERROR_LEVEL.equals(event.getKey())) {
			final String newSeverity = (String) event.getNewValue();
			final Object oldSeverity= event.getOldValue();
			if(newSeverity != null) {
				if(IPomVersionConstants.VALUE_IGNORE.equals(newSeverity)) {
					//we turned it off
					ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
				} else if(oldSeverity == null || IPomVersionConstants.VALUE_IGNORE.equals(oldSeverity)) {
					// we turned it on
					ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_BUILD);
				}
				validateWorkspace();
			}
		}
	}

	public void validateWorkspace() {
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IProject[] projects = root.getProjects();
		for (int i = 0; i < projects.length; i++) {
			validate(projects[i]);
		}
		RelEngPlugin.getPlugin().getPreferenceStore().setValue(IPomVersionConstants.WORKSPACE_VALIDATED, VERSION);
	}
}
