package eu.dnetlib.springutils.condbean.parser;

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

import java.io.IOException;
import java.io.InputStream;

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

import eu.dnetlib.springutils.condbean.parser.ast.AbstractExpression;
import fri.patterns.interpreter.parsergenerator.Lexer;
import fri.patterns.interpreter.parsergenerator.Parser;
import fri.patterns.interpreter.parsergenerator.ParserTables;
import fri.patterns.interpreter.parsergenerator.lexer.LexerBuilder;
import fri.patterns.interpreter.parsergenerator.lexer.LexerException;
import fri.patterns.interpreter.parsergenerator.parsertables.LALRParserTables;
import fri.patterns.interpreter.parsergenerator.syntax.SyntaxException;
import fri.patterns.interpreter.parsergenerator.syntax.builder.SyntaxBuilder;
import fri.patterns.interpreter.parsergenerator.syntax.builder.SyntaxSeparation;

public class CondBeanParserTest {

	private static final String CHECK_EXPRESSION = "check expression";
	private static final String PARSE_FAILED = "parse failed";
	private SyntaxSeparation separation;
	private LexerBuilder builder;
	private Lexer lexer;
	private ParserTables parserTables;
	private Parser parser;
	private AbstractExpression result;
	private ParserTables tables;
	private SyntaxBuilder builder2;
	private InputStream syntaxInput;

	@Before
	public void setUp() throws SyntaxException, LexerException, Exception {
		syntaxInput = CondBeanParser.class.getResourceAsStream("CondBeanParser.syntax");
		builder2 = new SyntaxBuilder(syntaxInput);
		lexer = builder2.getLexer();
		tables = new LALRParserTables(builder2.getParserSyntax());
		parser = new Parser(tables);
		parser.setLexer(lexer);
	}

	@Test
	public void testParser0() throws IOException {
		parser.setInput("1 || 1");
		assertTrue(PARSE_FAILED, parser.parse(new CondBeanParser()));
		result = (AbstractExpression) parser.getResult();
		assertTrue(CHECK_EXPRESSION, (Boolean) result.evaluate());
	}

	@Test
	public void testParser1() throws IOException {
		parser.setInput("!${some.existing.property} && ${some.value} == 3 || isdef(someBean) || 11");
		assertTrue(PARSE_FAILED, parser.parse(new CondBeanParser()));
		result = (AbstractExpression) parser.getResult();
		assertTrue(CHECK_EXPRESSION, (Boolean) result.evaluate());
	}

	@Test
	public void testParser2() throws IOException {
		parser.setInput("2 == 3");
		assertTrue(PARSE_FAILED, parser.parse(new CondBeanParser()));
		result = (AbstractExpression) parser.getResult();
		assertFalse(CHECK_EXPRESSION, (Boolean) result.evaluate());

	}

	@Test
	public void testParser3() throws IOException {
		parser.setInput("2==3");
		assertTrue(PARSE_FAILED, parser.parse(new CondBeanParser()));
		result = (AbstractExpression) parser.getResult();
		assertFalse(CHECK_EXPRESSION, (Boolean) result.evaluate());

	}

	@Test
	public void testParser4() throws IOException {
		parser.setInput("${some.value} == 3");
		assertTrue(PARSE_FAILED, parser.parse(new CondBeanParser()));
		result = (AbstractExpression) parser.getResult();
		assertFalse(CHECK_EXPRESSION, (Boolean) result.evaluate());
	}

	@Test
	public void testParser5() throws IOException {
		parser.setInput("!${some.existing.property} && ${some.value} == 3");
		assertTrue(PARSE_FAILED, parser.parse(new CondBeanParser()));
		result = (AbstractExpression) parser.getResult();
		assertFalse(CHECK_EXPRESSION, (Boolean) result.evaluate());

	}

	@Test
	public void testParser6() throws IOException {
		parser.setInput("${some.value} == 3 && !${some.existing.property}"); // give
		assertTrue(PARSE_FAILED, parser.parse(new CondBeanParser()));
		result = (AbstractExpression) parser.getResult();
		assertFalse(CHECK_EXPRESSION, (Boolean) result.evaluate());

	}

	@Test
	public void testParser7() throws IOException {
		parser.setInput("3 < 2 && 2<4");
		assertTrue(PARSE_FAILED, parser.parse(new CondBeanParser()));
		result = (AbstractExpression) parser.getResult();
		assertFalse(CHECK_EXPRESSION, (Boolean) result.evaluate());
	}

	@Test
	public void testParser8() throws IOException {
		parser.setInput("3 < 2 || 2<4");
		assertTrue(PARSE_FAILED, parser.parse(new CondBeanParser()));
		result = (AbstractExpression) parser.getResult();
		assertTrue(CHECK_EXPRESSION, (Boolean) result.evaluate());

	}

	public SyntaxSeparation getSeparation() {
		return separation;
	}

	public void setSeparation(final SyntaxSeparation separation) {
		this.separation = separation;
	}

	public LexerBuilder getBuilder() {
		return builder;
	}

	public void setBuilder(final LexerBuilder builder) {
		this.builder = builder;
	}

	public Lexer getLexer() {
		return lexer;
	}

	public void setLexer(final Lexer lexer) {
		this.lexer = lexer;
	}

	public ParserTables getParserTables() {
		return parserTables;
	}

	public void setParserTables(final ParserTables parserTables) {
		this.parserTables = parserTables;
	}

	public Parser getParser() {
		return parser;
	}

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

	public AbstractExpression getResult() {
		return result;
	}

	public void setResult(final AbstractExpression result) {
		this.result = result;
	}

	public ParserTables getTables() {
		return tables;
	}

	public void setTables(final ParserTables tables) {
		this.tables = tables;
	}

	public SyntaxBuilder getBuilder2() {
		return builder2;
	}

	public void setBuilder2(final SyntaxBuilder builder2) {
		this.builder2 = builder2;
	}

	public InputStream getSyntaxInput() {
		return syntaxInput;
	}

	public void setSyntaxInput(final InputStream syntaxInput) {
		this.syntaxInput = syntaxInput;
	}

}
