// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python.defaultProjectAwareService;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.impl.scopes.ModulesScope;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Function;
import com.intellij.util.concurrency.AppExecutorUtil;
import com.jetbrains.python.PythonFileType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

public final class PyDefaultProjectAwareModuleConfiguratorImpl<
  STATE,
  SERVICE extends PyDefaultProjectAwareService<STATE, SERVICE, APP_SERVICE, MODULE_SERVICE>,
  APP_SERVICE extends SERVICE,
  MODULE_SERVICE extends SERVICE> implements PyDefaultProjectAwareServiceModuleConfigurator {
  @NotNull
  private final PyDefaultProjectAwareServiceClasses<STATE, SERVICE, APP_SERVICE, MODULE_SERVICE> myClasses;
  @Nullable
  private final Function<Pair<Module, Collection<VirtualFile>>, ? extends STATE> myAutoDetector;

  public PyDefaultProjectAwareModuleConfiguratorImpl(@NotNull PyDefaultProjectAwareServiceClasses<STATE, SERVICE, APP_SERVICE, MODULE_SERVICE> classes) {
    this(classes, null);
  }

  public PyDefaultProjectAwareModuleConfiguratorImpl(@NotNull PyDefaultProjectAwareServiceClasses<STATE, SERVICE, APP_SERVICE, MODULE_SERVICE> classes,
                                                     @Nullable Function<Pair<Module, Collection<VirtualFile>>, ? extends STATE> autoDetector) {
    myClasses = classes;
    myAutoDetector = autoDetector;
  }

  @Override
  public void configureModule(@NotNull Module module, boolean newProject) {
    Function<Pair<Module, Collection<VirtualFile>>, ? extends STATE> detector = myAutoDetector;
    if (newProject || detector == null) {
      // For new project only copy from app.
      // For opened only copy if no autoconfiguration
      myClasses.copyFromAppToModule(module);
      return;
    }


    //Try to autodetect
    AppExecutorUtil.getAppScheduledExecutorService().schedule(() -> autodetectSettings(module, detector), 10, TimeUnit.SECONDS);
  }

  private void autodetectSettings(@NotNull Module module,
                                  @NotNull Function<Pair<Module, Collection<VirtualFile>>, ? extends STATE> detector) {
    final String extension = PythonFileType.INSTANCE.getDefaultExtension();
    // Module#getModuleScope() and GlobalSearchScope#getModuleScope() search only in source roots
    final GlobalSearchScope searchScope = new ModulesScope(Collections.singleton(module), module.getProject());

    final Collection<VirtualFile> pyFiles =
      ReadAction.compute(() -> FilenameIndex.getAllFilesByExt(module.getProject(), extension, searchScope));

    STATE state = detector.fun(Pair.create(module, pyFiles));
    if (state != null) {
      myClasses.getModuleService(module).loadState(state);
    }
    else {
      ApplicationManager.getApplication().invokeAndWait(() -> myClasses.copyFromAppToModule(module));
    }
  }
}

@@ -404,24 +404,69 @@
 dulesScope;%0A
+import com.intellij.openapi.project.Project;%0A
 import com.i
@@ -2917,16 +2917,59 @@
 e roots%0A
+    Project project = module.getProject();%0A
     fina
@@ -3054,40 +3054,22 @@
 e), 
-module.getP
+p
 roject
-()
 );%0A%0A   
- 
-final
  Col
@@ -3098,22 +3098,16 @@
 yFiles =
-%0A     
  ReadAct
@@ -3114,15 +3114,19 @@
 ion.
-compute
+nonBlocking
 (() 
@@ -3141,16 +3141,25 @@
 ameIndex
+%0A        
 .getAllF
@@ -3168,35 +3168,23 @@
 esByExt(
-module.getP
+p
 roject
-()
 , extens
@@ -3201,16 +3201,78 @@
 hScope))
+%0A        .inSmartMode(project)%0A        .executeSynchronously()
 ;%0A%0A    S

use non-blocking read-action EA-232243