// 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.

/*
 * @author max
 */
package com.intellij.openapi.project;

import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

final class ProjectLocatorImpl extends ProjectLocator {
  @Override
  @Nullable
  public Project guessProjectForFile(@Nullable VirtualFile file) {
    // StubUpdatingIndex calls this method very often, so, optimized implementation is required
    @SuppressWarnings("deprecation")
    Project project = ProjectCoreUtil.theOnlyOpenProject();
    if (project != null && !project.isDisposed()) {
      return project;
    }

    if (file != null) {
      project = getPreferredProject(file);
      if (project != null) {
        return project;
      }
    }

    ProjectManager projectManager = ProjectManager.getInstanceIfCreated();
    if (projectManager == null) {
      return null;
    }

    Project[] openProjects = projectManager.getOpenProjects();
    if (openProjects.length == 1) {
      return openProjects[0];
    }

    if (file == null) {
      return null;
    }

    return ReadAction.compute(() -> {
      for (Project openProject : projectManager.getOpenProjects()) {
        if (isUnder(openProject, file)) {
          return openProject;
        }
      }
      return null;
    });
  }

  // true if the file is either in the project content or in some excluded folder of the project
  private static boolean isUnder(@NotNull Project project, @NotNull VirtualFile file) {
    if (project.isDisposed()) {
      return false;
    }

    ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
    return fileIndex.isInContent(file) || fileIndex.isExcluded(file);
  }

  @Override
  @NotNull
  public Collection<Project> getProjectsForFile(@NotNull VirtualFile file) {
    ProjectManager projectManager = ProjectManager.getInstanceIfCreated();
    if (projectManager == null) {
      return Collections.emptyList();
    }

    Project[] openProjects = projectManager.getOpenProjects();
    if (openProjects.length == 0) {
      return Collections.emptyList();
    }

    List<Project> result = new SmartList<>();
    for (Project project : openProjects) {
      if (isUnder(project, file)) {
        result.add(project);
      }
    }
    return result;
  }
}
@@ -1899,67 +1899,8 @@
 ) %7B%0A
-    if (project.isDisposed()) %7B%0A      return false;%0A    %7D%0A%0A
     
@@ -2321,145 +2321,54 @@
     
-Project%5B%5D openProjects = projectManager.getOpenProjects();%0A    if (openProjects.length == 0) %7B%0A      return Collections.empty
+List%3CProject%3E result = new Smart
 List
+%3C%3E
 ();%0A    
 %7D%0A%0A 
@@ -2367,57 +2367,32 @@
     
-%7D%0A%0A    List%3CProject%3E result = new SmartList%3C%3E();%0A
+ReadAction.run(()-%3E %7B%0A  
     
@@ -2414,17 +2414,35 @@
 oject : 
-o
+projectManager.getO
 penProje
@@ -2444,20 +2444,24 @@
 Projects
+()
 ) %7B%0A
+  
       if
@@ -2496,16 +2496,18 @@
         
+  
 result.a
@@ -2519,24 +2519,34 @@
 oject);%0A
+        %7D%0A
       %7D%0A
     %7D%0A  
@@ -2537,21 +2537,23 @@
       %7D%0A
-
     %7D
+);
 %0A    ret

remove unnecessary check for isDisposed() because it should never fail