/*******************************************************************************
 * Copyright (c) 2011, 2018 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
 *******************************************************************************/
package org.eclipse.ocl.xtext.base.utilities;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.Diagnostician;
import org.eclipse.emf.ecore.util.EObjectValidator;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.utilities.LabelUtil;
import org.eclipse.ocl.xtext.base.cs2as.CS2AS;
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.CancelIndicator;
import org.eclipse.xtext.util.IAcceptor;
import org.eclipse.xtext.validation.AbstractInjectableValidator;
import org.eclipse.xtext.validation.CancelableDiagnostician;
import org.eclipse.xtext.validation.CheckMode;
import org.eclipse.xtext.validation.CheckType;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.validation.ResourceValidatorImpl;
import org.eclipse.xtext.validation.impl.ConcreteSyntaxEValidator;

import com.google.common.collect.Lists;

/**
 * PivotResourceValidator extends CS Resource validation to the referenced Pivot resources and attempts
 * to indicate Pivot validation problems in the appropriate CS context.
 */
public class PivotResourceValidator extends ResourceValidatorImpl
{
	public static class ValidationDiagnostic extends BasicDiagnostic implements Resource.Diagnostic
	{
		private ValidationDiagnostic(String message) {
			super(WARNING, EObjectValidator.DIAGNOSTIC_SOURCE, 0, message, null);
		}

		@Override
		public int getColumn() {
			return 0;		// This could be computed from the CS
		}

		@Override
		public int getLine() {
			return 0;		// This could be computed from the CS
		}

		@Override
		public String getLocation() {
			return null;		// This could be computed from the CS
		}

		public Integer getOffset() {
			return null;		// This could be computed from the CS
		}

		public Integer getLength() {
			return 10;		// This could be computed from the CS
		}
	}

	private static final Logger log = Logger.getLogger(PivotResourceValidator.class);
	public static final String HAS_SYNTAX_ERRORS = "has_syntax_errors";

	protected ValidationDiagnostic createDefaultDiagnostic(Diagnostician diagnostician, EObject pivotObject) {
		//		Object objectLabel = diagnostician.getObjectLabel(pivotObject);
		//		return new ValidationDiagnostic(EcorePlugin.INSTANCE.getString("_UI_DiagnosticRoot_diagnostic",
		//			new Object[] { objectLabel }), new Object[] { pivotObject });
		return new ValidationDiagnostic("");
	}

	protected void issueFromDiagnostics(IAcceptor<Issue> acceptor, ValidationDiagnostic diagnostic) {
		for (Diagnostic childDiagnostic : diagnostic.getChildren()) {
			//			System.out.println(" issueFromEValidatorDiagnostic " + childDiagnostic);
			issueFromEValidatorDiagnostic(childDiagnostic, acceptor);
		}
	}

	protected void performValidation(IAcceptor<Issue> acceptor, Resource asResource, CancelIndicator monitor) {
		//		System.out.println(Thread.currentThread().getName() + " performValidation " + NameUtil.debugSimpleName(asResource));
		Diagnostician diagnostician = getDiagnostician();
		Map<Object, Object> context = LabelUtil.createDefaultContext(diagnostician);
		//		List<Resource> resources = asResource.getResourceSet().getResources();
		//		for (int i = 0; i < resources.size(); i++) {
		Resource pResource = asResource; //resources.get(i);
		//			if (PivotConstants.ORPHANAGE_URI.equals(String.valueOf(pResource.getURI()))) {
		//				continue;		// GC may not have eliminated all the dangling references
		//			}
		//			System.out.println(" performValidation " + pResource.getURI() + " on " + Thread.currentThread().getName());
		removeValidationDiagnostics(pResource.getErrors());
		removeValidationDiagnostics(pResource.getWarnings());
		List<EObject> contents = pResource.getContents();
		for (int j = 0; j < contents.size(); j++) {		// Beware concurrent unload
			try {
				if (monitor.isCanceled())
					return;
				EObject pObject = contents.get(j);
				ValidationDiagnostic diagnostic = createDefaultDiagnostic(diagnostician, pObject);
				diagnostician.validate(pObject, diagnostic, context);
				if (!diagnostic.getChildren().isEmpty()) {
					if (diagnostic.getSeverity() == Diagnostic.ERROR) {
						pResource.getErrors().add(diagnostic);
					}
					else if (diagnostic.getSeverity() == Diagnostic.WARNING) {
						pResource.getWarnings().add(diagnostic);
					}
					issueFromDiagnostics(acceptor, diagnostic);
				}
			} catch (RuntimeException e) {
				if (!monitor.isCanceled()) {
					pResource.getErrors().add(new ValidationDiagnostic(e.getMessage()));
					//					log.error(e.getMessage(), e);
				}
			}
		}
		//		}
	}

	protected void removeValidationDiagnostics(List<Resource.Diagnostic> diagnostics) {
		//		System.out.println(Thread.currentThread().getName() + " removeValidationDiagnostics ");
		for (int i = diagnostics.size()-1; i >= 0; i--) {
			Resource.Diagnostic diagnostic = diagnostics.get(i);
			if (diagnostic instanceof ValidationDiagnostic) {
				diagnostics.remove(i);
			}
		}
	}

	/*	protected void reuseValidation(IAcceptor<Issue> acceptor, Resource asResource, CancelIndicator monitor) {
//		System.out.println(Thread.currentThread().getName() + " reuseValidation " + NameUtil.debugSimpleName(asResource));
		ResourceSet resourceSet = asResource.getResourceSet();
		if (resourceSet != null) {
			for (Resource pResource : resourceSet.getResources()) {
	//			System.out.println(" reuseValidation " + pResource.getURI() + " on " + Thread.currentThread().getName());
				for (Resource.Diagnostic diagnostic : pResource.getErrors()) {
					if (diagnostic instanceof ValidationDiagnostic) {
						issueFromDiagnostics(acceptor, (ValidationDiagnostic)diagnostic);
					}
				}
				for (Resource.Diagnostic diagnostic : pResource.getWarnings()) {
					if (diagnostic instanceof ValidationDiagnostic) {
						issueFromDiagnostics(acceptor, (ValidationDiagnostic)diagnostic);
					}
				}
			}
		}
	} */

	// FIXME BUG 389675 Remove duplication with respect to inherited method
	@Override
	public List<Issue> validate(Resource resource, final CheckMode mode, CancelIndicator mon) {
		//		System.out.println(Thread.currentThread().getName() + " validate start " + NameUtil.debugSimpleName(resource));
		//		System.out.println(new Date() + " Validate " + mode + " : " + csResource.getURI() + " on " + Thread.currentThread().getName());
		final CancelIndicator monitor = mon == null ? CancelIndicator.NullImpl : mon;
		resolveProxies(resource, monitor);
		if (monitor.isCanceled())
			return Collections.emptyList();

		final List<Issue> result = Lists.newArrayListWithExpectedSize(resource.getErrors().size()
			+ resource.getWarnings().size());
		try {
			IAcceptor<Issue> acceptor = createAcceptor(result);
			// Syntactical and linking errors
			// Collect EMF Resource Diagnostics
			if (mode.shouldCheck(CheckType.FAST)) {
				for (int i = 0; i < resource.getErrors().size(); i++) {
					if (monitor.isCanceled())
						return Collections.emptyList();
					issueFromXtextResourceDiagnostic(resource.getErrors().get(i), Severity.ERROR, acceptor);
				}

				for (int i = 0; i < resource.getWarnings().size(); i++) {
					if (monitor.isCanceled())
						return Collections.emptyList();
					issueFromXtextResourceDiagnostic(resource.getWarnings().get(i), Severity.WARNING, acceptor);
				}
			}

			if (monitor.isCanceled())
				return Collections.emptyList();
			boolean syntaxDiagFail = !result.isEmpty();
			logCheckStatus(resource, syntaxDiagFail, "Syntax");

			// Validation errors
			// Collect validator Diagnostics
			for (EObject ele : resource.getContents()) {
				try {
					if (monitor.isCanceled())
						return Collections.emptyList();
					Diagnostician diagnostician = getDiagnostician();
					Map<Object, Object> options = LabelUtil.createDefaultContext(diagnostician);
					options.put(CheckMode.KEY, mode);
					options.put(CancelableDiagnostician.CANCEL_INDICATOR, monitor);
					// disable concrete syntax validation, since a semantic model that has been parsed
					// from the concrete syntax always complies with it - otherwise there are parse errors.
					options.put(ConcreteSyntaxEValidator.DISABLE_CONCRETE_SYNTAX_EVALIDATOR, Boolean.TRUE);
					// see EObjectValidator.getRootEValidator(Map<Object, Object>)
					boolean hasSyntaxError = false;
					if (resource instanceof XtextResource) {
						options.put(AbstractInjectableValidator.CURRENT_LANGUAGE_NAME, ((XtextResource) resource).getLanguageName());
						if (resource instanceof BaseCSResource) {
							BaseCSResource csResource = (BaseCSResource)resource;
							@NonNull List<Resource.Diagnostic> errors = csResource.getErrors();
							hasSyntaxError = ElementUtil.hasSyntaxError(errors);
							if (hasSyntaxError) {
								options.put(PivotResourceValidator.HAS_SYNTAX_ERRORS, Boolean.TRUE);
							}
						}
					}
					if (!hasSyntaxError) {
						Diagnostic diagnostic = getDiagnostician().validate(ele, options);
						if (!diagnostic.getChildren().isEmpty()) {
							for (Diagnostic childDiagnostic : diagnostic.getChildren()) {
								issueFromEValidatorDiagnostic(childDiagnostic, acceptor);
							}
						} else {
							issueFromEValidatorDiagnostic(diagnostic, acceptor);
						}
					}
				} catch (RuntimeException e) {
					if (!monitor.isCanceled()) {		// Fix Bug 462544 working around Xtext Bug 461764
						log.error(e.getMessage(), e);
					}
				}
			}
		} catch (RuntimeException e) {
			log.error(e.getMessage(), e);
		}
		if (monitor.isCanceled())
			return Collections.emptyList();
		if (resource instanceof BaseCSResource) {
			BaseCSResource csResource = (BaseCSResource)resource;
			CS2AS cs2as = csResource.findCS2AS();
			if (cs2as != null) {
				Resource asResource = cs2as.getASResource();
				IAcceptor<Issue> acceptor = createAcceptor(result);
				//				if (mode.shouldCheck(CheckType.EXPENSIVE)) {
				performValidation(acceptor, asResource, monitor);
				//				}
				//				else {
				//					reuseValidation(acceptor, asResource, monitor);
				//				}
			}
		}
		//		System.out.println(Thread.currentThread().getName() + " validate end " + NameUtil.debugSimpleName(resource));
		return result;
	}


	private void logCheckStatus(final Resource resource, boolean parserDiagFail, String string) {
		if (log.isDebugEnabled()) {
			log.debug(string + " check " + (parserDiagFail ? "FAIL" : "OK") + "! Resource: " + resource.getURI());
		}
	}


}
