package pp.s1184725.boppi.test;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.logging.*;

import org.apache.commons.lang3.tuple.Pair;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import pp.s1184725.boppi.*;

public class ParserTest {
	static final Path directory = Paths.get("src/pp/s1184725/boppi/test/parsing/");
	private List<LogRecord> log;
	
	static private List<LogRecord> parseAndGetLog(String code) {
		Pair<BasicParser, List<LogRecord>> pair = BasicParserHelper.getParserWithLog(code, Logger.getAnonymousLogger());
		pair.getLeft().program();
		return pair.getRight();
	}
	
	static private List<LogRecord> parseAndGetLog(Path code) throws IOException {
		Pair<BasicParser, List<LogRecord>> pair = BasicParserHelper.getParserWithLog(code, Logger.getAnonymousLogger());
		pair.getLeft().program();
		return pair.getRight();
	}
	
	@Test
	public void correctExpressionTest() throws Exception {
		log = parseAndGetLog(directory.resolve("simpleExpression.boppi"));
		assertThat(log, empty());
	}
	
	@Test
	public void wrongExpressionTest() {
		log = parseAndGetLog("");
		assertThat(log, not(empty()));
		assertThat(log.get(0).getLevel(), is(Level.SEVERE));

		log = parseAndGetLog("~");
		assertThat(log, not(empty()));
		assertThat(log.get(0).getLevel(), is(Level.SEVERE));

		log = parseAndGetLog("0A");
		assertThat(log, hasSize(1));
		assertThat(log.get(0).getLevel(), is(Level.SEVERE));

		log = parseAndGetLog("do");
		assertThat(log, hasSize(1));
		assertThat(log.get(0).getLevel(), is(Level.SEVERE));

		log = parseAndGetLog("true true");
		assertThat(log, hasSize(1));
		assertThat(log.get(0).getLevel(), is(Level.SEVERE));
	}

	@Test
	public void correctVariableTest() throws Exception {
		log = parseAndGetLog(directory.resolve("simpleVariable.boppi"));
		assertThat(log, empty());
	}
	
	@Test
	public void wrongVariableTest() {
		log = parseAndGetLog("var");
		assertThat(log, hasSize(1));
		assertThat(log.get(0).getLevel(), is(Level.SEVERE));

		log = parseAndGetLog("var bool 5");
		assertThat(log, hasSize(1));
		assertThat(log.get(0).getLevel(), is(Level.SEVERE));

		log = parseAndGetLog("var 'c' varname");
		assertThat(log, not(empty()));
		assertThat(log.get(0).getLevel(), is(Level.SEVERE));

		log = parseAndGetLog("var bool; true true;");
		assertThat(log, hasSize(2));
		assertThat(log.get(0).getLevel(), is(Level.SEVERE));
	}

	@Test
	public void correctScopeTest() throws Exception {
		log = parseAndGetLog(directory.resolve("simpleScope.boppi"));
		assertThat(log, empty());
	}

	@Test
	public void correctConditionalTest() throws Exception {
		log = parseAndGetLog(directory.resolve("if.boppi"));
		assertThat(log, empty());

		log = parseAndGetLog(directory.resolve("while.boppi"));
		assertThat(log, empty());
	}
	
}
