package org.jetbrains.plugins.groovy.mvc;

import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.event.HyperlinkEvent;

/**
 * @author Sergey Evdokimov
 */
public class MvcProjectWithoutLibraryNotificator implements StartupActivity, DumbAware {

  @Override
  public void runActivity(@NotNull final Project project) {
    AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();

    try {
      if (JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_OBJECT, GlobalSearchScope.allScope(project)) == null) {
        return; // If indexes is corrupted JavaPsiFacade.findClass() can't find classes during StartupActivity (may be it's a bug).
                // So we can't determine whether exists Grails library or not.
      }

      Pair<Module, MvcFramework> pair = findModuleWithoutLibrary(project);

      if (pair != null) {
        final MvcFramework framework = pair.second;
        final Module module = pair.first;

        new Notification(framework.getFrameworkName() + ".Configure",
                         framework.getFrameworkName() + " SDK not found.",
                         "<html><body>Module '" +
                         module.getName() +
                         "' has no " +
                         framework.getFrameworkName() +
                         " SDK. <a href='create'>Configure SDK</a></body></html>", NotificationType.INFORMATION,
                         new NotificationListener.Adapter() {
                           @Override
                           protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) {
                             MvcConfigureNotification.configure(framework, module);
                           }
                         }).notify(project);
      }
    }
    finally {
      accessToken.finish();
    }
  }

  @Nullable
  private static Pair<Module, MvcFramework> findModuleWithoutLibrary(Project project) {
    MvcFramework[] frameworks = MvcFramework.EP_NAME.getExtensions();

    for (Module module : ModuleManager.getInstance(project).getModules()) {
      for (MvcFramework framework : frameworks) {
        VirtualFile appRoot = framework.findAppRoot(module);
        if (appRoot != null && appRoot.findChild("application.properties") != null) {
           if (!framework.hasFrameworkJar(module)) {
             return Pair.create(module, framework);
           }
        }
      }
    }

    return null;
  }
}

@@ -1077,24 +1077,149 @@
  project) %7B%0A
+    ApplicationManager.getApplication().executeOnPooledThread(new Runnable() %7B%0A      @Override%0A      public void run() %7B%0A    
     AccessTo
@@ -1294,24 +1294,28 @@
 ionLock();%0A%0A
+    
     try %7B%0A  
@@ -1308,24 +1308,28 @@
       try %7B%0A
+    
       if (Ja
@@ -1458,24 +1458,28 @@
 ) %7B%0A        
+    
 return; // I
@@ -1590,16 +1590,20 @@
 a bug).%0A
+    
         
@@ -1675,27 +1675,35 @@
  not.%0A      
-%7D%0A%0A
+    %7D%0A%0A    
       Pair%3CM
@@ -1768,24 +1768,28 @@
 ct);%0A%0A      
+    
 if (pair != 
@@ -1800,24 +1800,28 @@
 ) %7B%0A        
+   
+ 
 final MvcFra
@@ -1856,24 +1856,28 @@
 nd;%0A        
+    
 final Module
@@ -1899,32 +1899,36 @@
 first;%0A%0A        
+   
+ 
 new Notification
@@ -1990,32 +1990,36 @@
                 
+    
 framework.getFra
@@ -2077,16 +2077,20 @@
         
+   
+ 
 %22%3Chtml%3E%3C
@@ -2131,16 +2131,20 @@
         
+    
 module.g
@@ -2179,16 +2179,20 @@
         
+   
+ 
 %22' has n
@@ -2193,24 +2193,28 @@
  has no %22 +%0A
+    
             
@@ -2282,16 +2282,20 @@
         
+  
+  
 %22 SDK. %3C
@@ -2391,32 +2391,36 @@
                 
+    
 new Notification
@@ -2463,24 +2463,28 @@
             
+  
+  
 @Override%0A  
@@ -2477,24 +2477,28 @@
   @Override%0A
+    
             
@@ -2640,16 +2640,20 @@
         
+  
+  
 MvcConfi
@@ -2718,34 +2718,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -2787,24 +2787,36 @@
 ;%0A      
+    
 %7D%0A    
+ 
-%7D%0A
+   %7D%0A    
     fina
@@ -2827,16 +2827,20 @@
 %7B%0A      
+ 
+   
 accessTo
@@ -2857,17 +2857,37 @@
 ();%0A    
-%7D
+    %7D%0A      %7D%0A    %7D);
 %0A  %7D%0A%0A  

Check Grails SDK in background thread, not in the AWT. +review CR-IU @gromopert