package eu.dnetlib.data.collective.transformation.rulelanguage;

import static org.junit.Assert.*;

import java.io.StringReader;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.junit.Test;
import org.svenson.JSONParser;

import eu.dnetlib.data.collective.transformation.engine.functions.IdentifierExtract;
import eu.dnetlib.data.collective.transformation.engine.functions.Lookup;
import eu.dnetlib.data.collective.transformation.engine.functions.RegularExpression;
import eu.dnetlib.data.collective.transformation.rulelanguage.Argument.Type;
import eu.dnetlib.data.collective.transformation.rulelanguage.parser.ASTMyScript.SCRIPTTYPE;
import eu.dnetlib.data.collective.transformation.rulelanguage.visitor.RuleLanguageVisitor;


public class RuleLanguageTest {

	private static final String declareScript = "declare_script \"abc\";\r\n";
	private static final String endScript = "end";
	private StringBuilder scriptBuilder;
	
	private RuleLanguageVisitor parseValid(String stmt) {
		RuleLanguageParser rlp = new RuleLanguageParser();
		StringReader r = new StringReader(stmt);
		rlp.parse(r);
		return rlp.getVisitor();
	}
	
	@Test
	public void parseMinimalScript(){
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals("abc", v.getScriptName());
		assertEquals(SCRIPTTYPE.MAINSCRIPT, v.getScriptType());
	}
	
	@Test
	public void parseNameSpace(){
		final String ns_decl = "declare_ns somePrefix = \"http://someHost/somePath/someVersion/1.0/\";\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ns_decl);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals("http://someHost/somePath/someVersion/1.0/", v.getNamespaceDeclarations().get("somePrefix"));
	}
	
	@Test
	public void parsePreprocessing(){
		final String preproc = "preprocess abc = dblookup(\"select * from xyz\");\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(preproc);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertTrue(v.getPreprocessings().get(0).containsKey("dblookup"));
	}
	
	@Test
	public void parsePreprocessingBlacklist(){
		final String preproc = "blacklist(\"//RESOURCE_IDENTIFIER/@value\");\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(preproc);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertTrue(v.getPreprocessings().get(0).containsKey("blacklist"));
		assertEquals("//RESOURCE_IDENTIFIER/@value", v.getPreprocessings().get(0).get("blacklist"));
		Argument argXpath = new Argument(Type.INPUTFIELD, v.getPreprocessings().get(0).get("blacklist"));
		assertEquals("//RESOURCE_IDENTIFIER/@value", argXpath.getArgument());
	}
		
	@Test
	public void testLookup(){
		final String rule = "dc:relation = lookup(xpath:\"//proc:provenance\", \"name\");\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(rule);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		Set<IRule> s = v.getElementMappingRules().get("dc:relation");
		assertNotNull(s);
		assertEquals(1, s.size());
		assertEquals("lookup", (s.toArray(new Rules[0]))[0].getFunctionCall().getExternalFunctionName());
		assertEquals("//proc:provenance", (s.toArray(new Rules[0]))[0].getFunctionCall().getParameters().get(Lookup.paramExprIdentifier));
		assertEquals("name", (s.toArray(new Rules[0]))[0].getFunctionCall().getParameters().get(Lookup.paramExprProperty));
	}
	
	@Test
	public void testLookupVar(){
//		final String rule = "$var = ";
		final String rule = "dc:relation = lookup($var0, \"name\");\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(rule);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		Set<IRule> s = v.getElementMappingRules().get("dc:relation");
		assertNotNull(s);
		assertEquals(1, s.size());
		assertEquals("lookup", (s.toArray(new Rules[0]))[0].getFunctionCall().getExternalFunctionName());
		assertEquals("$var0", (s.toArray(new Rules[0]))[0].getFunctionCall().getParameters().get(Lookup.paramExprIdentifier));
		assertEquals("name", (s.toArray(new Rules[0]))[0].getFunctionCall().getParameters().get(Lookup.paramExprProperty));
	}
	
	@Test
	public void parseAssignXpathRule(){
		final String ruleAssignWithXpathExpr = "dri:title = xpath:\"//dc:title\";\r\n";
		final String comment = "// some comment\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(comment);
		scriptBuilder.append(ruleAssignWithXpathExpr);		
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		Set<IRule> s  = v.getElementMappingRules().get("dri:title");
		assertNotNull(s);
		assertEquals(1, s.size());
		assertEquals("//dc:title", (s.toArray(new Rules[0]))[0].getXpath());
	}
	
	@Test
	public void parseConstantRule(){
		final String ruleConstant = "dri:CobjMDformats = \"oai_dc\";\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleConstant);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s  = v.getElementMappingRules().get("dri:CobjMDformats");
		for (IRule r: s){
			assertEquals("oai_dc", ((Rules)r).getConstant());
		}		
	}
	
	@Test
	public void parseFuncGetValueRule(){
		final String ruleFuncGetvalue = "static dri:repositoryName = getValue(profileField,[$job.recordprefix, def]);\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleFuncGetvalue);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s  = v.getElementMappingRules().get("dri:repositoryName");
		for (IRule r: s){
			assertEquals("getValue", ((Rules)r).getFunctionCall().getExternalFunctionName());
			//assertEquals("dnetExt:getValue(profileField)", r.getFunction());
			assertEquals(2, ((Rules)r).getFunctionCall().getArguments().size());
			assertEquals("$job.recordprefix", ((Rules)r).getFunctionCall().getArguments().get(0).getArgument());
			assertEquals(true, ((Rules)r).isStatic());
		}		
	}
	
	@Test
	public void parseFuncGetValueXpathArgsRule(){
		final String ruleFuncGetvalue = "dri:repositoryName = getValue(profileField,[xpath:\"//node1\", xpath:\"//node2\"]);\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleFuncGetvalue);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s  = v.getElementMappingRules().get("dri:repositoryName");
		for (IRule r: s){
			assertEquals("getValue", ((Rules)r).getFunctionCall().getExternalFunctionName());
			//assertEquals("dnetExt:getValue(profileField)", r.getFunction());
			assertEquals(2, ((Rules)r).getFunctionCall().getArguments().size());
			assertEquals(false, ((Rules)r).isStatic());
			Argument arg1 = ((Rules)r).getFunctionCall().getArguments().get(0);
			assertTrue(arg1.isInputField());
			assertEquals("//node1", arg1.getArgument());
			Argument arg2 = ((Rules)r).getFunctionCall().getArguments().get(1);
			assertTrue(arg2.isInputField());
			assertEquals("//node2", arg2.getArgument());
		}	
	}
	
	@Test
	public void parseFuncConvert(){
		final String ruleFuncConvert_withPrefixes = "somePrefix:lv2 = Convert(xpath:\"/dc:metadata/dc:language\",LangVocab);\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleFuncConvert_withPrefixes);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s  = v.getElementMappingRules().get("somePrefix:lv2");
		for (IRule r: s){
			assertEquals("convert", ((Rules)r).getFunctionCall().getExternalFunctionName());			
			//assertEquals("dnetExt:convert(/metadata/language,LangVocab)", r.getFunction());
		}
	}
	
	@Test
	public void parseFuncExtract(){
		final String ruleFuncExtract = "somePrefix:lv = Extract(Language);\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleFuncExtract);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s  = v.getElementMappingRules().get("somePrefix:lv");
		for (IRule r: s){
			assertEquals("extract", ((Rules)r).getFunctionCall().getExternalFunctionName());			
			assertEquals("Language", ((Rules)r).getFunctionCall().getParameters().get("feature"));
		}
	}
	
	@Test
	public void parseFuncConcat(){
		final String ruleFuncConcat = "sp:lv = concat(\"value abc\", $var1);\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleFuncConcat);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s = v.getElementMappingRules().get("sp:lv");
		for (IRule r: s){
			assertEquals("concat", ((Rules)r).getFunctionCall().getExternalFunctionName());			
			assertEquals(2, ((Rules)r).getFunctionCall().getParamList().size());
		}
	}
	
	@Test
	public void parseFuncSplit(){
		final String ruleFuncSplit = "%template1 = split(xpath:\"/dc:creator\", \"dc:creator\", \";\");\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleFuncSplit);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getTemplateMappingRules().size());
		IRule r = v.getTemplateMappingRules().get("%template1");
		assertEquals("split", ((Rules)r).getFunctionCall().getExternalFunctionName());
		
	}
	
	@Test
	public void parseFuncConvertWithAttr(){
		final String ruleFuncConvert_withAttribute = "somePrefix:lv3 = Convert(xpath:\"/dc:metadata/language/@attr\",LangVocab);\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleFuncConvert_withAttribute);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s  = v.getElementMappingRules().get("somePrefix:lv3");
		for (IRule r: s){
			assertEquals("convert", ((Rules)r).getFunctionCall().getExternalFunctionName());			
			//assertEquals("dnetExt:convert(/dc:metadata/language[@attr],LangVocab)", r.getFunction());
		}
	}
	
	@Test
	public void parseFuncConvertWithOptParams(){
		final String ruleFuncConvert_withAttribute = "somePrefix:lv3 = Convert(xpath:\"/dc:metadata/dc:date\",DateISO, \"YYYY-MM-DD\", \"MIN\" );\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleFuncConvert_withAttribute);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s  = v.getElementMappingRules().get("somePrefix:lv3");
		for (IRule r: s){
			assertEquals("convert", ((Rules)r).getFunctionCall().getExternalFunctionName());			
			//assertEquals("dnetExt:convert(/dc:metadata/language[@attr],LangVocab)", r.getFunction());
		}
	}
	
	@Test
	public void parseFuncIdentifierExtract(){
		final String ruleFuncIdentiferExtract = "pref:elem = identifierExtract('[\"dc:identifer\", \"dc:relation\"]', xpath:\"/\", 'regExpr');\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleFuncIdentiferExtract);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString()); 
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s  = v.getElementMappingRules().get("pref:elem");
		for (IRule r: s){
			assertEquals("identifierExtract", ((Rules)r).getFunctionCall().getExternalFunctionName());
			String xpathJsonString = ((Rules)r).getFunctionCall().getParameters().get(IdentifierExtract.paramXpathExprJson);
			assertEquals("[\"dc:identifer\", \"dc:relation\"]", xpathJsonString);
			List<String> xpathExprList = JSONParser.defaultJSONParser().parse(List.class, xpathJsonString);
			assertEquals(2, xpathExprList.size());
		}
	}
	
	@Test
	public void parseConditionalRuleWithDistinctTargetElements(){
		final String ruleConditional = "if xpath:\"//dc:metadata/dc:language\" somePrefix:a = \"primaryRule\"; else somePrefix:b = \"secondaryRule\";\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleConditional);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		assertEquals(2, v.getElementMappingRules().size());
		Set<IRule> s1 = v.getElementMappingRules().get("somePrefix:a");
		assertEquals(1, s1.size());
		Set<IRule> s2 = v.getElementMappingRules().get("somePrefix:b");
		assertEquals(1, s2.size());
		for (IRule rCon: s1){
			Rules r = (Rules)rCon;
			assertEquals("//dc:metadata/dc:language", r.getCondition().getConditionExpression());
			assertTrue(r.hasCondition());
			assertTrue(r.getCondition().isPrimary(r));
		}
		for (IRule rCon: s2){
			Rules r = (Rules)rCon;
			assertEquals("//dc:metadata/dc:language", r.getCondition().getConditionExpression());
			assertTrue(r.hasCondition());
			if (r.getCondition().isPrimary(r)){
				assertNotSame(r.getCondition().getSecondaryRule(), r);
				assertEquals(r.getCondition().getPrimaryRule(), r);
			}
			assertNotSame(r.getCondition().getPrimaryRule().getUniqueName(), r.getCondition().getSecondaryRule().getUniqueName());
		}
	}
	
	@Test
	public void parseConditionalRuleWithParamAsConditionExpression(){
		final String ruleConditional = "if xpath:\"$var1='Aggregator'\" somePrefix:a = \"primaryRule\"; else somePrefix:b = \"secondaryRule\";\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleConditional);
		scriptBuilder.append(endScript);		
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		assertEquals(2, v.getElementMappingRules().size());
		Set<IRule> s1 = v.getElementMappingRules().get("somePrefix:a");
		assertEquals(1, s1.size());
		Set<IRule> s2 = v.getElementMappingRules().get("somePrefix:b");
		assertEquals(1, s2.size());
		for (IRule rCon: s1){
			Rules r = (Rules)rCon;
			assertEquals("$var1='Aggregator'", r.getCondition().getConditionExpression());
			assertTrue(r.hasCondition());
			assertTrue(r.getCondition().isPrimary(r));
		}
		for (IRule rCon: s2){
			Rules r = (Rules)rCon;
			assertEquals("$var1='Aggregator'", r.getCondition().getConditionExpression());
			assertTrue(r.hasCondition());
			if (r.getCondition().isPrimary(r)){
				assertNotSame(r.getCondition().getSecondaryRule(), r);
				assertEquals(r.getCondition().getPrimaryRule(), r);
			}
			assertNotSame(r.getCondition().getPrimaryRule().getUniqueName(), r.getCondition().getSecondaryRule().getUniqueName());
		}
	}
	
	@Test
	public void parseConditionalRuleWithSameTargetElements(){
		final String ruleConditional = "if xpath:\"//dc:metadata/dc:language\" somePrefix:a = \"primaryRule\"; else somePrefix:a = \"secondaryRule\";\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleConditional);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		assertEquals(1, v.getElementMappingRules().size());
		// the output element 'somePrefix:a' has two alternative rules
		Set<IRule> s = v.getElementMappingRules().get("somePrefix:a");
		assertEquals(2, s.size());
		for (IRule rCon: s){
			Rules r = (Rules)rCon;
			assertEquals("//dc:metadata/dc:language", r.getCondition().getConditionExpression());
			if (r.getCondition().isPrimary(r)){
				assertEquals(r.getCondition().getPrimaryRule(), r);
			}else{
				assertEquals(r.getCondition().getSecondaryRule(), r);
			}
			assertNotSame(r.getCondition().getPrimaryRule(), r.getCondition().getSecondaryRule());
			assertEquals(r.getCondition().getPrimaryRule().getUniqueName(), r.getCondition().getSecondaryRule().getUniqueName());
		}		
	}
	
	@Test
	public void parseConditionalRuleWithApplyOnField(){
		final String rule = "apply xpath:\"//dc:identifier\" if xpath:\"starts-with(., 'http:')\" dr:CobjIdentifier = xpath:\".\"; else dc:identifier = xpath:\".\";\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(rule);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		assertEquals(2, v.getElementMappingRules().size());
		Set<IRule> s1 = v.getElementMappingRules().get("dr:CobjIdentifier");
		for (IRule rCon: s1){
			Rules r = (Rules)rCon;
			assertEquals("//dc:identifier", r.getCondition().getApplyExpression());
		}
	}

	@Test
	public void testCopy(){
		final String rule = "dc:title = copy(\"dc:title\", \"//dc:title\", \"@*|node()\");\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(rule);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		Set<IRule> s = v.getElementMappingRules().get("dc:title");
		assertNotNull(s);
		assertEquals("dc:title", (s.toArray(new Rules[0]))[0].getTemplateMatch());
	}

	@Test
	public void testSkip(){
		final String rule = "dc:title = skipRecord();\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(rule);
		scriptBuilder.append(endScript);
		
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		assertNotNull(v);
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s1 = v.getElementMappingRules().get("dc:title");
		assertNotNull(s1);
		for (IRule rSkip: s1){
			Rules r = (Rules)rSkip;
			assertNotNull(r);
			assertFalse(r.hasSet());
			assertTrue(r.isSkip());			
		}

	}
	
	@Test
	public void parseSetRule(){
		final String rule = "dc:identifier = set(\"CONST\" , @type = \"ABC\"; , @lang = \"ger\";);";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(rule);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		assertEquals(1, v.getElementMappingRules().size());
		Iterator<String> it = v.getElementMappingRules().keySet().iterator();
		while (it.hasNext()){
			System.out.println("key: " + it.next());
		}
		Set<IRule> s1 = v.getElementMappingRules().get("dc:identifier");
		for (IRule rSet: s1){
			Rules r = (Rules)rSet;
			assertTrue(r.hasSet());
			List<Rules> pendingRules = r.getRulesSet().getPendingRules();
			assertEquals(2,pendingRules.size());
			for (Rules pRule: pendingRules){
				assertTrue(pRule.getAttribute().equals("type") || 
						pRule.getAttribute().equals("lang"));
			}
			
		}
	}
	
	@Test
	public void parseRuleWithVariable(){
		final String ruleLine = "$abc = xpath:\"//dc:creator\";\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleLine);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		assertEquals(0, v.getElementMappingRules().size());
		assertEquals(1, v.getVariableMappingRules().size());
	}
	
	@Test
	public void parseRuleWithStaticVariable(){
		final String ruleLine = "static $abc = RegExpr(xpath:\"//someExpr1\", xpath:\"//someExpr2\", \"s/[x1]/[x2]\");\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleLine);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		assertEquals(0, v.getElementMappingRules().size());
		assertEquals(1, v.getVariableMappingRules().size());
		assertEquals(true, ((Rules)v.getVariableMappingRules().get("$abc")).isStatic());
	}
	
//	@Test
	public void parseRegExpr(){
		final String ruleLine = "somePrefix:someElement = RegExpr(xpath:\"//someExpr1\", xpath:\"//someExpr2\", \"s/[x1]/[x2]\");\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleLine);
		scriptBuilder.append(endScript);
		@SuppressWarnings("unused")
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
	}
	
	@Test
	public void parseRegExpr2(){
		final String ruleLine = "somePrefix:someElement = RegExpr($job.recordidentifier, xpath:\"//someExpr2\", \"s/[x1]/[x2]\");\r\n";
		scriptBuilder = new StringBuilder();
		scriptBuilder.append(declareScript);
		scriptBuilder.append(ruleLine);
		scriptBuilder.append(endScript);
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
		assertEquals(1, v.getElementMappingRules().size());
		Set<IRule> s  = v.getElementMappingRules().get("somePrefix:someElement");
		for (IRule r: s){
			assertEquals("regExpr", ((Rules)r).getFunctionCall().getExternalFunctionName());
			//assertEquals("dnetExt:getValue(profileField)", r.getFunction());
			assertEquals("$job.recordidentifier", ((Rules)r).getFunctionCall().getParameters().get(RegularExpression.paramExpr1));
//			assertEquals("$job.recordprefix", ((Rules)r).getFunctionCall().getArguments().get(0).getArgument());
//			assertEquals(true, ((Rules)r).isStatic());
		}		
	}
	
	@Test
	public void parseDc2DmfScript(){
		scriptBuilder = new StringBuilder();
		scriptBuilder.append("declare_script \"MainSample\";\r\n");
	       scriptBuilder.append("declare_ns dr = \"http://www.driver-repository.eu/namespace/dr\";\r\n");
	       scriptBuilder.append("declare_ns dri = \"http://www.driver-repository.eu/namespace/dri\";\r\n");
	       scriptBuilder.append("declare_ns dc = \"http://purl.org/dc/elements/1.1/\";\r\n");

	       scriptBuilder.append("dr:objectIdentifier = xpath:\"//dri:objIdentifier\";\r\n");
	       scriptBuilder.append("dr:dateOfCollection = getValue(CURRENTDATE, []);\r\n");
	       scriptBuilder.append("dr:CobjContentSynthesis = empty;\r\n");
	       scriptBuilder.append("dr:CobjTypology = \"Textual\";\r\n");
	       scriptBuilder.append("dr:CobjModel = \"OAI\";\r\n");
	       scriptBuilder.append("dr:CobjMdFormats = \"oai_dc\";\r\n");
	       scriptBuilder.append("dr:CobjDescriptionSynthesis = empty;\r\n");
	       scriptBuilder.append("//dr:aggregatorName = getValue(PROFILEFIELD, [\"transformationmanager-service-profile-id\", xpath:\"//PROPERTY/@key='name'\"]);\r\n");
	       scriptBuilder.append("dr:aggregatorInstitution = empty;\r\n");
	       scriptBuilder.append("dr:repositoryName = getValue(PROFILEFIELD, [xpath:\"//dri:repositoryId\", xpath:\"//CONFIGURATION/OFFICIAL_NAME\"]);\r\n");
	       scriptBuilder.append("dr:repositoryLink = getValue(PROFILEFIELD, [xpath:\"//dri:repositoryId\", xpath:\"//REPOSITORY_WEBPAGE\"]);\r\n");
	       scriptBuilder.append("dr:repositoryCountry = getValue(PROFILEFIELD, [xpath:\"//dri:repositoryId\", xpath:\"//COUNTRY\"]);\r\n");
	       scriptBuilder.append("dr:repositoryInstitution = getValue(PROFILEFIELD, [xpath:\"//dri:repositoryId\", xpath:\"//REPOSITORY_INSTITUTION\"]);\r\n");
	       scriptBuilder.append("dc:creator = xpath:\"//dc:creator\";\r\n");
	       scriptBuilder.append("dc:title = xpath:\"//dc:title\";\r\n");
	       scriptBuilder.append("dc:subject = xpath:\"//dc:subject\";\r\n");
//	       scriptBuilder.append("dr:CobjCategory = Convert(xpath:\"//dc:type\", TextTypologies);\r\n");
//	       scriptBuilder.append("dc:language = Convert(xpath:\"//dc:language\", Languages);\r\n");
//	       scriptBuilder.append("dc:dateAccepted = Convert(xpath:\"//dc:date\", DateISO8601);\r\n");
	       scriptBuilder.append("apply xpath:\"//dc:identifier\" if xpath:\"starts-with(., 'http')\" dc:identifier = xpath:\".\"; else dr:CobjIdentifier = xpath:\".\";\r\n");
	       scriptBuilder.append("apply xpath:\"//dc:relation\" if xpath:\"starts-with(., 'http')\" dc:identifier = Convert(xpath:\"//dc:type\", TextTypologies); else dr:CobjIdentifier = xpath:\".\";\r\n");
	       scriptBuilder.append("dc:publisher = xpath:\"//dc:publisher\";\r\n");
	       scriptBuilder.append("dc:source = xpath:\"//dc:source\";\r\n");
	       scriptBuilder.append("dc:contributor = xpath:\"//dc:contributor\";\r\n");
	       scriptBuilder.append("dc:relation = xpath:\"//dc:relation\";\r\n");
	       scriptBuilder.append("dc:description = xpath:\"//dc:description\";\r\n");
	       scriptBuilder.append("end\r\n"); 		
		@SuppressWarnings("unused")
		RuleLanguageVisitor v = parseValid(scriptBuilder.toString());
	}
}
