package eu.dnetlib.springutils.condbean.parser;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.IOException;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import eu.dnetlib.springutils.condbean.parser.ast.AndExpression;
import eu.dnetlib.springutils.condbean.parser.ast.EqualityExpression;
import eu.dnetlib.springutils.condbean.parser.ast.OrExpression;
import eu.dnetlib.springutils.condbean.parser.ast.RelationalExpression;
import eu.dnetlib.springutils.condbean.parser.ast.SysProperty;


public class RunccExpressionParserTest { //NOPMD
	
	private static final String CHECK_EXPRESSION = "check expression value";
	private static final String EXPRESSION_TYPE = "check expression type";
	private String parseInput;
	private RunccExpressionParser parser;
	
	@Before
	public void setProperties() {
		System.setProperty("some.existing.property", "pippo");
		
		parser = new RunccExpressionParser();
		parser.setCondBeanParser(new CondBeanParser());
	}	
	
	@After
	public void cleanupProperties() {
		System.clearProperty("some.existing.property");
	}
	
	@Test
    public void test0() throws IOException {
    	parseInput = "${some.existing.property}";
		
		assertTrue(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof SysProperty);
	}
	
	@Test
    public void test1() throws IOException {
    	parseInput = "false && false";
		
		assertFalse(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof AndExpression);
	}
	
	@Test
    public void test2() throws IOException {
    	parseInput = "1<2";
		
		assertTrue(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof RelationalExpression);
	}
	
	@Test
	public void test3() throws IOException {
		
		parseInput = "!${some.existing.property} && ${some.value} == 3 || isdef(someBean) || 11";
		assertTrue(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof OrExpression);
	}

	@Test
	public void test4() throws IOException {
		
		parseInput = "2 == 3";
		assertFalse(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof EqualityExpression);

	}

	@Test
	public void test5() throws IOException {
		
		parseInput = "\"3\"==3";
		assertFalse(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof EqualityExpression);
	}

	@Test
	public void test6() throws IOException {
		
		parseInput = "${some.value} == 3";
		assertFalse(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof EqualityExpression);
	}

	@Test
	public void test7() throws IOException {
		
		parseInput = "!${some.existing.property} && ${some.value} == 3";
		assertFalse(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof AndExpression);
	}

	@Test
	public void test8() throws IOException {
		
		parseInput = "${some.value} == 3 && !${some.existing.property}";
		assertFalse(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof AndExpression);
	}

	@Test
	public void test9() throws IOException {
		
		parseInput = "3 < 2 && 2<4";
		assertFalse(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof AndExpression);
	}

	@Test
	public void test10() throws IOException	{
		
		parseInput = "3 < 2 || 2<4";
		assertTrue(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof OrExpression);
	}
	
	@Test
    public void test11() throws IOException {
    	parseInput = "3==3";
		
		assertTrue(CHECK_EXPRESSION, parser.expressionValue(parseInput));
		assertTrue(EXPRESSION_TYPE, parser.getTopRule(parseInput) instanceof EqualityExpression);
	}

	public String getParseInput() {
		return parseInput;
	}

	public void setParseInput(final String parseInput) {
		this.parseInput = parseInput;
	}

	public RunccExpressionParser getParser() {
		return parser;
	}

	public void setParser(final RunccExpressionParser parser) {
		this.parser = parser;
	}	
}
