package de.simonscholz.junit4converter.converters;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;

public class JTestCaseConverter implements Converter {
	private static final String JTESTCASE_CLASSNAME = "JTestCase";
	private static final String JTESTCASE_QUALIFIEDNAME = "com.foo.res.JTestCase";
	private static final String DBRULE_QUALIFIEDNAME = "com.foo.res.BisonDBRule";
	private static final String DBRULE_CLASSNAME = "BisonDBRule";
	private static final String DBRULE_VARIABLENAME = "_functions";
	private static final String RULE_QUALIFIEDNAME = "org.junit.Rule";

	private final ASTRewrite rewriter;
	private final ImportRewrite importRewriter;
	private boolean wasModified;

	JTestCaseConverter(ASTRewrite rewriter, ImportRewrite importRewriter) {
		this.rewriter = rewriter;
		this.importRewriter = importRewriter;
	}

	@Override
	public boolean isConveratable(TypeDeclaration typeDeclaration) {
		return isJTestCase(typeDeclaration.getSuperclassType());
	}

	private boolean isJTestCase(Type superclassType) {
		if (superclassType != null && superclassType.isSimpleType()) {
			SimpleType superType = (SimpleType) superclassType;
			return JTESTCASE_CLASSNAME.equals(superType.getName()
					.getFullyQualifiedName());
		}
		return false;
	}

	@Override
	public void convert(TypeDeclaration typeDeclaration) {
		wasModified = true;
		Type superclassType = typeDeclaration.getSuperclassType();
		removeJTestSuperClass(superclassType);
		addDBRule(typeDeclaration);
	}

	@Override
	public boolean wasConverted() {
		return wasModified;
	}

	private void addDBRule(TypeDeclaration typeDeclaration) {
		StringBuilder variableBuilder = new StringBuilder();
		variableBuilder.append("@Rule \n");
		variableBuilder.append("public ").append(DBRULE_CLASSNAME).append(' ')
				.append(DBRULE_VARIABLENAME).append(" = new ")
				.append(DBRULE_CLASSNAME).append("();");
		ASTNode variableDeclarationNode = rewriter.createStringPlaceholder(
				variableBuilder.toString(), ASTNode.EMPTY_STATEMENT);

		ListRewrite listRewrite = rewriter.getListRewrite(typeDeclaration,
				TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
		listRewrite.insertFirst(variableDeclarationNode, null);
		importRewriter.addImport(DBRULE_QUALIFIEDNAME);
		importRewriter.addImport(RULE_QUALIFIEDNAME);
	}

	private void removeJTestSuperClass(Type superType) {
		rewriter.remove(superType, null);
		importRewriter.removeImport(JTESTCASE_QUALIFIEDNAME);
	}
}

@@ -45,16 +45,40 @@
 rters;%0A%0A
+import java.util.List;%0A%0A
 import o
@@ -110,16 +110,67 @@
 STNode;%0A
+import org.eclipse.jdt.core.dom.MethodDeclaration;%0A
 import o
@@ -201,24 +201,67 @@
 SimpleType;%0A
+import org.eclipse.jdt.core.dom.Statement;%0A
 import org.e
@@ -969,16 +969,84 @@
 t.Rule%22;
+%0A%09private static final String GETSESSIONMETHODCALL = %22getSession()%22;
 %0A%0A%09priva
@@ -1942,16 +1942,61 @@
 ation);%0A
+%09%09replaceCallsOfSuperClass(typeDeclaration);%0A
 %09%7D%0A%0A%09@Ov
@@ -2871,32 +2871,32 @@
 perType, null);%0A
-
 %09%09importRewriter
@@ -2937,11 +2937,769 @@
 AME);%0A%09%7D
+%0A%0A%09private void replaceCallsOfSuperClass(TypeDeclaration typeDeclaration) %7B%0A%09%09MethodDeclaration%5B%5D methods = typeDeclaration.getMethods();%0A%09%09for (MethodDeclaration methodDeclaration : methods) %7B%0A%09%09%09List%3CStatement%3E statements = methodDeclaration.getBody()%0A%09%09%09%09%09.statements();%0A%09%09%09for (Statement statement : statements) %7B%0A%09%09%09%09String statementAsString = statement.toString();%0A%09%09%09%09if (statementAsString.contains(GETSESSIONMETHODCALL)) %7B%0A%09%09%09%09%09String newStatement = statementAsString.replace(%0A%09%09%09%09%09%09%09GETSESSIONMETHODCALL, DBRULE_VARIABLENAME + '.'%0A%09%09%09%09%09%09%09%09%09+ GETSESSIONMETHODCALL);%0A%09%09%09%09%09ASTNode delegateToRule = rewriter.createStringPlaceholder(%0A%09%09%09%09%09%09%09newStatement, ASTNode.EMPTY_STATEMENT);%0A%09%09%09%09%09rewriter.replace(statement, delegateToRule, null);%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D
 %0A%7D%0A

add proof of concept replace method calls