package org.intellij.joe.inspections.optimization;

import com.intellij.codeInspection.InspectionManager;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpressionStatement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiStatement;
import com.intellij.psi.PsiAssignmentExpression;
import com.intellij.psi.PsiJavaToken;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.PsiBinaryExpression;
import org.intellij.joe.JavaOptimizationEnginePlugin;
import org.intellij.joe.inspections.AbstractExpressionStatementInspection;
import org.intellij.joe.inspections.AbstractExpressionStatementVisitor;

/**
 *
 *
 * @author Loïc Lefèvre
 */
public class OptimizationInspection extends AbstractExpressionStatementInspection
{
    public String getDisplayName()
    {
        return "Simple Optimization";
    }

    public String getGroupDisplayName()
    {
        return "Java Optimization Engine";
    }

    public String getShortName()
    {
        return "Optimization";
    }

    /**
     * Return an expression statement visitor.
     *
     * @param inspectionManager
     * @param isOnTheFly
     * @return a class visitor
     */
    protected AbstractExpressionStatementVisitor createExpressionStatementVisitor( InspectionManager inspectionManager,
                                                                                   boolean isOnTheFly )
    {
        return new OptimizationVisitor( this, inspectionManager, isOnTheFly );
    }

    protected class OptimizationVisitor extends AbstractExpressionStatementVisitor
    {
        protected OptimizationVisitor( final OptimizationInspection optimizationInspection,
                                       final InspectionManager inspectionManager,
                                       final boolean isOnTheFly )
        {
            super( optimizationInspection, inspectionManager, isOnTheFly );
        }

        public void visitClass( final PsiClass aClass )
        {
            // do not manage interfaces
            if( aClass.isInterface() )
            {
                return;
            }

            PsiMethod[] methods = aClass.getMethods();
            for( int i = 0; i < methods.length; i++ )
            {
                // JavaOptimizationEnginePlugin.log( "methods["+i+"]="+methods[i]+"\n"+methods[i].getBody());
                if( methods[i].getBody() != null )
                {
                    PsiStatement[] statements = methods[i].getBody().getStatements();
                    for( int j = 0; j < statements.length; j++ )
                    {
                        // JavaOptimizationEnginePlugin.log( "statements["+j+"]="+statements[j]);
                        if( statements[j] instanceof PsiExpressionStatement)
                            visitExpressionStatement( (PsiExpressionStatement)statements[j] );
                    }
                }
            }
        }

        public void visitExpressionStatement(PsiExpressionStatement psiExpressionStatement)
        {
            final PsiElement[] children = psiExpressionStatement.getChildren();
            if( children != null && children.length == 2 )
            {
                JavaOptimizationEnginePlugin.log( "psiExpressionStatement="+psiExpressionStatement+", number of children="+psiExpressionStatement.getChildren().length );

                if( children[0] instanceof PsiAssignmentExpression &&
                    children[1] instanceof PsiJavaToken )
                {
                    final PsiJavaToken jT = (PsiJavaToken)children[1];

                    if( jT.getTokenType() == JavaTokenType.SEMICOLON )
                    {
                        final PsiAssignmentExpression aE = (PsiAssignmentExpression)children[0];

                        if( aE.getOperationSign().getTokenType() == JavaTokenType.EQ )
                        {
                            JavaOptimizationEnginePlugin.log( "left  : "+aE.getLExpression() );
                            JavaOptimizationEnginePlugin.log( "right : "+aE.getRExpression() );

                            if( aE.getLExpression() instanceof PsiReferenceExpression )
                            {
                                final PsiReferenceExpression rE = (PsiReferenceExpression)aE.getLExpression();
                                JavaOptimizationEnginePlugin.log( "rE  : "+rE );

                                if( aE.getRExpression() instanceof PsiBinaryExpression )
                                {
                                    final PsiBinaryExpression bE = (PsiBinaryExpression)aE.getRExpression();

                                    JavaOptimizationEnginePlugin.log( "bE  : "+bE );

									...
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
