package net.bitpot.railways.models;

import com.intellij.openapi.module.Module;
import net.bitpot.railways.gui.RailwaysIcons;
import net.bitpot.railways.utils.RailwaysPsiUtils;
import org.jetbrains.plugins.ruby.rails.model.RailsApp;
import org.jetbrains.plugins.ruby.ruby.lang.psi.controlStructures.classes.RClass;
import org.jetbrains.plugins.ruby.ruby.lang.psi.controlStructures.methods.RMethod;
import org.jetbrains.plugins.ruby.ruby.lang.psi.controlStructures.methods.Visibility;

import javax.swing.*;

/**
 * Contains information about controller action.
 *
 * @author Basil Gren
 *         on 23.11.2014.
 */
public class RailsActionInfo {

    // Class which is referenced by route action, it might not have
    // implementation of the method, as the method can be inherited.
    private RClass psiClass = null;

    // Route action method.
    private RMethod psiMethod = null;


    public RClass getPsiClass() {
        return psiClass;
    }

    public RMethod getPsiMethod() {
        return psiMethod;
    }


    public Icon getIcon() {
        Visibility vis = getMethodVisibility();
        if (vis != null)
            switch (vis) {
                case PRIVATE:
                case PROTECTED:
                    return RailwaysIcons.NODE_METHOD;

                case PUBLIC:
                    return RailwaysIcons.NODE_ROUTE_ACTION;
            }

        return RailwaysIcons.NODE_ERROR;
    }


    public Visibility getMethodVisibility() {
        if (getPsiMethod() == null)
            return null;

        return psiMethod.getVisibility();
    }


    public void update(Module module, String controllerName, String actionName) {
        RailsApp app = RailsApp.fromModule(module);
        update(app, controllerName, actionName);
    }

    // TODO: cache found classes and methods to reuse found values.
    public void update(RailsApp app, String controllerShortName, String actionName) {
        if ((app == null) || controllerShortName.isEmpty()) {
            psiMethod = null;
            psiClass = null;
            return;
        }

        if (psiClass != null && !psiClass.isValid()) {
            psiMethod = null;
            psiClass = null;
        }

        // Find psiClass if it's not specified or already invalid.
        if (psiClass == null) {
            String qualifiedName = RailwaysPsiUtils.getControllerClassNameByShortName(
                    controllerShortName);
            psiClass = RailwaysPsiUtils.findControllerClass(app, qualifiedName);
        }

        if (psiClass != null) {
            if (psiMethod == null || !psiMethod.isValid()) {
                psiMethod = RailwaysPsiUtils.findControllerMethod(app,
                        psiClass, actionName);
            } else {
                // Even if psiMethod is valid, its name can be different - it
                // usually happens when user edits method name - the psiElement
                // is just updated.
                if (!psiMethod.getName().equals(actionName))
                    psiMethod = null;
            }
        }
    }

}

@@ -499,16 +499,42 @@
 swing.*;
+%0Aimport java.util.Objects;
 %0A%0A/**%0A *
@@ -2089,32 +2089,153 @@
 urn;%0A        %7D%0A%0A
+        String qualifiedName =%0A                RailwaysPsiUtils.getControllerClassNameByShortName(controllerShortName);%0A%0A
         if (psiC
@@ -2250,16 +2250,17 @@
 null && 
+(
 !psiClas
@@ -2262,32 +2262,116 @@
 iClass.isValid()
+ %7C%7C%0A                !Objects.equals(psiClass.getFQN().getFullPath(), qualifiedName))
 ) %7B%0A            
@@ -2531,137 +2531,8 @@
 ) %7B%0A
-            String qualifiedName = RailwaysPsiUtils.getControllerClassNameByShortName(%0A                    controllerShortName);%0A
     

Fix live detection of controller class name change