package jce.manipulation;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.internal.corext.refactoring.sef.SelfEncapsulateFieldRefactoring;
import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
import org.eclipse.ltk.core.refactoring.CreateChangeOperation;
import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;

import jce.util.ProgressMonitorAdapter;

/**
 * {@link ASTVisitor} class for {@link Type}s to the manipulate inheritance relations.
 * @author Timur Saglam
 */
@SuppressWarnings("restriction")
public class FieldEncapsulationVisitor extends ASTVisitor {
    private static final Logger logger = LogManager.getLogger(FieldEncapsulationVisitor.class.getName());

    /**
     * Basic constructor.
     */
    public FieldEncapsulationVisitor() {
    }

    public void encapsulateField(IField field) {
        try {
            SelfEncapsulateFieldRefactoring refactoring = new SelfEncapsulateFieldRefactoring(field);
            CheckConditionsOperation checkCondOp = new CheckConditionsOperation(refactoring, CheckConditionsOperation.ALL_CONDITIONS);
            CreateChangeOperation createChangeOp = new CreateChangeOperation(checkCondOp, RefactoringStatus.WARNING);
            PerformChangeOperation performChangeOp = new PerformChangeOperation(createChangeOp);
            IWorkspace workspace = ResourcesPlugin.getWorkspace();
            workspace.run(performChangeOp, new ProgressMonitorAdapter(logger));
        } catch (JavaModelException exception) {
            exception.printStackTrace();
        } catch (CoreException exception) {
            exception.printStackTrace();
        }
    }

    @Override
    public boolean visit(TypeDeclaration node) {
        if (!node.isInterface()) { // if is class, manipulate inheritance:
            System.out.println("Node: " + node.getName()); // TODO
            for (FieldDeclaration field : node.getFields()) {
                System.out.println("Field: " + field); // TODO
                VariableDeclarationFragment fragment = (VariableDeclarationFragment) field.fragments().get(0);
                IJavaElement element = fragment.resolveBinding().getJavaElement();
                if (element instanceof IField) {
                    encapsulateField((IField) element);
                } else {
                    throw new RuntimeException("Critical problem with field encapsulation. IJavaElement is not IField: " + element + " IS "
                            + element.getClass().getName()); // TODO
                }
            }
        }
        return super.visit(node);
    }
}
@@ -456,58 +456,8 @@
 on;%0A
-import org.eclipse.jdt.core.dom.IVariableBinding;%0A
 impo
@@ -1320,82 +1320,107 @@
   * 
-Basic constructor.%0A     */%0A    public FieldEncapsulationVisitor() %7B
+Encapsulates a specific %7B@link IField%7D.%0A     * @param field is the specific %7B@link IField%7D.
 %0A    
-%7D%0A
+ */
 %0A   
@@ -1460,24 +1460,58 @@
 eld field) %7B
+ // TODO (HIGH) Test this process.
 %0A        try
@@ -2458,187 +2458,57 @@
     
-System.out.println(%22Node: %22 + node.getName()); // TODO%0A            for (FieldDeclaration field : node.getFields()) %7B%0A                System.out.println(%22Field: %22 + field); // TODO
+for (FieldDeclaration field : node.getFields()) %7B
 %0A   
@@ -3036,16 +3036,47 @@
  // TODO
+ (HIGH) Improve error handling.
 %0A       

Clean up. Removed debug output. COMMENT: Added and removed TODO comments.