package de.simonscholz.junit4converter.converters;

import static de.simonscholz.junit4converter.converters.JTestCaseConverter.DBRULE_VARIABLENAME;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;

public class RedirectCallsOfSuperClassToRuleMethodBodyVisitor extends
		ASTVisitor {
	private ASTRewrite rewriter;
	private List<String> toBeReplacedMethodCalls;

	public RedirectCallsOfSuperClassToRuleMethodBodyVisitor(ASTRewrite rewriter) {
		this.rewriter = rewriter;
		createListOfToBeReplacedMethods();
	}

	private void createListOfToBeReplacedMethods() {
		toBeReplacedMethodCalls = new ArrayList<>();
		toBeReplacedMethodCalls.add("getSession()");
		toBeReplacedMethodCalls.add("addImplementation(");
		toBeReplacedMethodCalls.add("createMockView(");
		toBeReplacedMethodCalls.add("addImplementation(");
		toBeReplacedMethodCalls.add("addDatatypeProvider(");
	}

	@Override
	public boolean visit(Block methodBody) {
		for (Statement currentStatement : getStatements(methodBody)) {
			String statement = currentStatement.toString();
			for (String toBeReplacedMethodCall : toBeReplacedMethodCalls) {
				boolean shouldReplace = statement.contains(toBeReplacedMethodCall)
						&& !shouldNotBeReplaced(statement,
								toBeReplacedMethodCall);
				if (shouldReplace) {
					String newStatement = createReplacingStatement(statement,
							toBeReplacedMethodCall);
					ASTNode delegateToRule = rewriter.createStringPlaceholder(
							newStatement, ASTNode.EMPTY_STATEMENT);
					rewriter.replace(currentStatement, delegateToRule, null);
				}
			}
		}
		return true;
	}

	private boolean shouldNotBeReplaced(String statement,
			String toBeReplacedMethodCall) {
		int startOfReplacement = statement.indexOf(toBeReplacedMethodCall);
		int previousIndex = startOfReplacement - 1;
		if (previousIndex >= 0) {
			char previousChar = statement.charAt(previousIndex);
			return previousChar == '.';
		}
		return false;
	}

	private String createReplacingStatement(String currentStatement,
			String toReplacingMethodCall) {
		String newMethodCall = DBRULE_VARIABLENAME + '.'
				+ toReplacingMethodCall;
		String newStatement = currentStatement.replace(toReplacingMethodCall,
				newMethodCall);
		return newStatement;
	}

	@SuppressWarnings("unchecked")
	private List<Statement> getStatements(Block methodBody) {
		return methodBody.statements();
	}

}

@@ -977,61 +977,8 @@
 %22);%0A
-%09%09toBeReplacedMethodCalls.add(%22addImplementation(%22);%0A
 %09%09to
@@ -1028,16 +1028,16 @@
 der(%22);%0A
+
 %09%7D%0A%0A%09@Ov
@@ -1305,16 +1305,23 @@
 tatement
+%0A%09%09%09%09%09%09
 .contain
@@ -1356,35 +1356,39 @@
 %09%09%09%09&& !
-shouldNotBeReplaced
+isCalledOnAnotherObject
 (stateme
@@ -1773,27 +1773,31 @@
 ean 
-shouldNotBeReplaced
+isCalledOnAnotherObject
 (Str

improve method name / remove duplicate entry in list