/**
 * Copyright (c) 2016 committers of YAKINDU 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:
 *     committers of YAKINDU - initial API and implementation
 */
package org.yakindu.sct.generator.core.execution;

import java.util.List;

import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.validation.CheckMode;
import org.eclipse.xtext.validation.IResourceValidator;
import org.eclipse.xtext.validation.Issue;
import org.yakindu.base.base.NamedElement;
import org.yakindu.sct.generator.core.console.IConsoleLogger;
import org.yakindu.sct.generator.core.filesystem.DefaultFileSystemAccessFactory;
import org.yakindu.sct.generator.core.filesystem.ISCTFileSystemAccess;
import org.yakindu.sct.generator.core.library.ICoreLibraryHelper;
import org.yakindu.sct.model.sgen.GeneratorEntry;

import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
import com.google.inject.name.Named;

/**
 * 
 * @author andreas muelder - Initial contribution and API
 * 
 */
public abstract class AbstractGeneratorEntryExecutor implements IGeneratorEntryExecutor {

	@Inject
	protected DefaultFileSystemAccessFactory factory;
	@Inject
	protected IConsoleLogger logger;
	@Inject
	protected ICoreLibraryHelper helper;
	@Inject
	protected IResourceValidator validator;
	@Inject(optional = true)
	@Named(SKIP_VALIDATION)
	protected boolean skipValidation = false;

	protected abstract void execute(ISCTFileSystemAccess access, GeneratorEntry generatorEntry);

	@Override
	public void execute(GeneratorEntry entry) {
		NamedElement element = (NamedElement) entry.getElementRef();
		if (valid(entry)) {
			logger.log("Generating '" + element.getName() + "' to target project ..."
					+ helper.getTargetProjectValue(entry).getStringValue());
			try {
				execute(factory.create(entry), entry);
			} catch (Exception ex) {
				logger.logError(ex);
			} finally {
				logger.log("done...");
			}
		}

	}

	protected void logStart(GeneratorEntry entry) {
		String elementName = ((NamedElement) entry.getElementRef()).getName();
		String targetProject = helper.getTargetProjectValue(entry).getStringValue();
		logger.log(String.format("Generating %s to target project %s ...", elementName, targetProject));
	}

	protected void logEnd(GeneratorEntry entry) {
		logger.log("done...");
	}

	protected void logException(Exception ex) {
		logger.logError(ex);
	}

	protected boolean valid(GeneratorEntry entry) {
		if (skipValidation) {
			logger.log("Validation skipped...");
			return true;
		}
		List<Issue> issues = validator.validate(entry.getElementRef().eResource(), CheckMode.ALL, null);
		Iterable<Issue> errors = Iterables.filter(issues, new Predicate<Issue>() {
			@Override
			public boolean apply(Issue input) {
				return input.getSeverity() == Severity.ERROR;
			}
		});
		if (!Iterables.isEmpty(errors)) {
			logger.log("The referenced model contains errors and could not be generated:");
			for (Issue issue : errors) {
				logger.log(issue.getMessage());
			}
			return false;
		}
		return true;
	}
}

@@ -460,16 +460,54 @@
 .List;%0A%0A
+import org.eclipse.emf.ecore.EObject;%0A
 import o
@@ -1838,229 +1838,46 @@
 %7B%0A%09%09
-NamedElement element = (NamedElement) entry.getElementRef();%0A%09%09if (valid(entry)) %7B%0A%09%09%09logger.log(%22Generating '%22 + element.getName() + %22' to target project ...%22%0A%09%09%09%09%09+ helper.getTargetProjectValue(entry).getStringValue());
+logStart(entry);%0A%09%09if (valid(entry)) %7B
 %0A%09%09%09
@@ -1986,55 +1986,29 @@
 %09%09%09%7D
- finally %7B
 %0A%09%09
+%7D%0A
 %09%09log
-ger.log(%22done...%22);%0A%09%09%09%7D%0A%09%09%7D%0A
+End(entry);
 %0A%09%7D%0A
@@ -2063,55 +2063,133 @@
 %7B%0A%09%09
-String elementName = ((NamedElement) entry.getE
+EObject elementRef = entry.getElementRef();%0A%09%09String elementName = elementRef instanceof NamedElement%0A%09%09%09%09? ((NamedElement) e
 leme
@@ -2193,18 +2193,16 @@
 ementRef
-()
 ).getNam
@@ -2204,16 +2204,44 @@
 etName()
+%0A%09%09%09%09: elementRef.toString()
 ;%0A%09%09Stri
@@ -2352,18 +2352,20 @@
 erating 
+'
 %25s
+'
  to targ
@@ -2375,18 +2375,20 @@
 project 
+'
 %25s
+'
  ...%22, e
@@ -2484,15 +2484,65 @@
 log(
-%22done..
+((NamedElement) entry.getElementRef()).getName() + %22 done
 .%22);
@@ -3111,16 +3111,79 @@
 ed model
+(%22 + ((NamedElement) entry.getElementRef()).getName()%0A%09%09%09%09%09+ %22)
  contain

check elementRef is named witin generator executor (#1107)