package eu.dnetlib.data.utility.cleaner;

import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;

import eu.dnetlib.data.utility.cleaner.rmi.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 String groovyRule;
	private Closure closure;

	private GroovyShell groovyShell = new GroovyShell();
	
	@Override
	protected String calculateNewValue(String oldValue, String context, String id) throws CleanerException {
		try {
			if (context != null) {
				log.warn("The context param [" + context + "] will be ignored");
			}
			log.info("Executing groovy closure on value " + oldValue);
			if(closure == null) {
				closure = (Closure) groovyShell.evaluate("{ input -> " + groovyRule + "}");
			}
			return (String) closure.call(oldValue);
		} catch (Exception e) {
			log.error("Failed Groovy execution, groovyRule: " + groovyRule + ", input: " + oldValue, e);
			throw new CleanerException("Error executing groovy", e);
		}
	}

	@Override
	protected Map<String, String> verifyValue(String value, String context, String id) throws CleanerException {
		return null;
	}
	
	@Required
	public void setGroovyRule(String groovyRule) {
		this.groovyRule = groovyRule;
	}

}
