package eu.dnetlib.data.cleaner;

import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import eu.dnetlib.rmi.data.CleanerException;
import groovy.lang.Closure;
import groovy.lang.GroovyShell;

/**
 * @author michele
 *
 *         Groovy rules must be declared in a CleanerDS profile, some examples:
 *
 *         <RULE xpath="..." groovy=
 *         "(input =~ /X/).replaceAll('Y')" /> <RULE xpath="..." groovy="'CONSTANT'" /> <RULE xpath="..." groovy="input.toUpperCase()" />
 */

public class GroovyRule extends XPATHCleaningRule {

	private static final Log log = LogFactory.getLog(GroovyRule.class); // NOPMD by marko on 11/24/08 5:02 PM

	private final String groovyRule;
	private final Closure<String> closure;

	private final GroovyShell groovyShell = new GroovyShell();

	@SuppressWarnings("unchecked")
	public GroovyRule(final String groovyRule) {
		this.groovyRule = groovyRule;
		this.closure = (Closure<String>) this.groovyShell.evaluate("{ input -> " + groovyRule + "}");
	}

	@Override
	protected String calculateNewValue(final String oldValue) throws CleanerException {
		try {
			log.info("Executing groovy closure on value " + oldValue);
			return this.closure.call(oldValue);
		} catch (final Exception e) {
			log.error("Failed Groovy execution, groovyRule: " + this.groovyRule + ", input: " + oldValue, e);
			throw new CleanerException("Error executing groovy", e);
		}
	}

	@Override
	protected Map<String, String> verifyValue(final String value) throws CleanerException {
		return null;
	}

	@Override
	public String toString() {
		return "GROOVY: " + this.groovyRule;
	}
}
