package com.intellij.compiler;

import com.intellij.ProjectTopics;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PsiTestUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author nik
 */
public class RefreshOutputDirectoriesTest extends BaseCompilerTestCase {
  private int myRootsChangedCount;

  public void testSingleModule() {
    final VirtualFile file = createFile("src/A.java", "public class A {}");
    final Module module = addModule("m", file.getParent());
    subscribeToRootChanges();
    make(module);
    assertOutputDirectoriesRefreshed(module);
  }

  public void testManyModulesWithInheritedOutputPath() {
    doTestManyModules(false);
  }

  public void testManyModulesWithCustomOutputPaths() {
    doTestManyModules(true);
  }

  private void doTestManyModules(boolean inheritOutputPath) {
    List<Module> modules = new ArrayList<>();
    for (int i = 0; i < 15; i++) {
      VirtualFile file = createFile("m" + i + "/src/A" + i + ".java", "public class A" + i + "{}");
      final String moduleName = "m" + i;
      VirtualFile sourceRoot = file.getParent();
      Module module;
      if (inheritOutputPath) {
        module = addModule(moduleName, sourceRoot);
      }
      else {
        module = createModule(moduleName);
        VirtualFile contentRoot = sourceRoot.getParent();
        PsiTestUtil.addContentRoot(module, contentRoot);
        PsiTestUtil.addSourceRoot(module, sourceRoot);
        ModuleRootModificationUtil.setModuleSdk(module, getTestProjectJdk());
        PsiTestUtil.setCompilerOutputPath(module, contentRoot.getUrl() + "/classes", false);
      }
      modules.add(module);

    }
    Module[] modulesArray = modules.toArray(new Module[modules.size()]);
    subscribeToRootChanges();
    make(modulesArray);
    assertOutputDirectoriesRefreshed(modulesArray);
  }

  private void subscribeToRootChanges() {
    myProject.getMessageBus().connect(getTestRootDisposable()).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
      @Override
      public void rootsChanged(ModuleRootEvent event) {
        myRootsChangedCount++;
      }
    });
  }

  private void assertOutputDirectoriesRefreshed(Module... modules) {
    assertEquals(1, myRootsChangedCount);
    for (Module module : modules) {
      File dir = getOutputDir(module, false);
      VirtualFile outputDir = LocalFileSystem.getInstance().findFileByIoFile(dir);
      assertNotNull("output directory wasn't refreshed: " + dir.getAbsolutePath(), outputDir);
    }
    System.out.println("myRootsChangedCount = " + myRootsChangedCount);
  }
}

@@ -360,24 +360,76 @@
 irtualFile;%0A
+import com.intellij.testFramework.PlatformTestUtil;%0A
 import com.i
@@ -2183,16 +2183,18 @@
 Array);%0A
+  
   %7D%0A%0A  p
@@ -2228,24 +2228,72 @@
 Changes() %7B%0A
+    PlatformTestUtil.saveProject(getProject());%0A
     myProjec

test fix