package com.intellij.compiler;

import com.intellij.openapi.module.Module;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PsiTestUtil;

import static com.intellij.util.io.TestFileSystemBuilder.fs;

/**
 * @author nik
 */
public class ModuleCompileScopeTest extends BaseCompilerTestCase {
  @Override
  protected boolean useExternalCompiler() {
    return true;
  }

  public void testCompileFile() {
    VirtualFile a = createFile("src/A.java", "class A{}");
    createFile("src/B.java", "class B{}");
    Module module = addModule("a", a.getParent());
    compile(true, a);
    assertOutput(module, fs().file("A.class"));
    make(module);
    assertOutput(module, fs().file("A.class").file("B.class"));
    assertModulesUpToDate();
  }

  public void testForceCompileUpToDateFile() {
    VirtualFile a = createFile("src/A.java", "class A{}");
    Module module = addModule("a", a.getParent());
    make(module);
    assertOutput(module, fs().file("A.class"));
    final VirtualFile output = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(getOutputDir(module));
    assertNotNull(output);
    final VirtualFile classFile = output.findChild("A.class");
    assertNotNull(classFile);
    deleteFile(classFile);
    make(module);
    assertOutput(module, fs());
    compile(true, a);
    assertOutput(module, fs().file("A.class"));
    assertModulesUpToDate();
  }

  public void testForceCompileUpToDateFileAndDoNotCompileDependentTestClass() {
    VirtualFile a = createFile("src/A.java", "class A{ public static void foo(int param) {} }");
    VirtualFile b = createFile("testSrc/B.java", "class B { void bar() {A.foo(10);}}");
    Module module = addModule("a", a.getParent(), b.getParent());
    make(module);
    assertOutput(module, fs().file("A.class"), false);
    assertOutput(module, fs().file("B.class"), true);
    final VirtualFile output = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(getOutputDir(module, false));
    assertNotNull(output);
    final VirtualFile testOutput = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(getOutputDir(module, true));
    assertNotNull(testOutput);
    final VirtualFile classFile = output.findChild("A.class");
    assertNotNull(classFile);
    final VirtualFile testClassFile = testOutput.findChild("B.class");
    assertNotNull(testClassFile);
    deleteFile(classFile);
    deleteFile(testClassFile);
    make(module);
    assertOutput(module, fs());
    compile(true, a);
    assertOutput(module, fs().file("A.class"), false);
    assertOutput(module, fs(), true);
    boolean upToDate = getCompilerManager().isUpToDate(getCompilerManager().createProjectCompileScope(myProject));
    assertFalse("Module should not be up to date", upToDate);
  }

  public void testMakeTwoModules() {
    VirtualFile file1 = createFile("m1/src/A.java", "class A{}");
    Module m1 = addModule("m1", file1.getParent());
    VirtualFile file2 = createFile("m2/src/B.java", "class B{}");
    Module m2 = addModule("m2", file2.getParent());
    make(m1);
    assertOutput(m1, fs().file("A.class"));
    assertNoOutput(m2);
    make(m2);
    assertOutput(m2, fs().file("B.class"));
    assertModulesUpToDate();
  }

  public void testExcludedFile() {
    VirtualFile a = createFile("src/a/A.java", "package a; class A{}");
    createFile("src/b/B.java", "package b; class B{}");
    Module m = addModule("m", a.getParent().getParent());
    PsiTestUtil.addExcludedRoot(m, a.getParent());
    make(m);
    assertOutput(m, fs().dir("b").file("B.class"));

    changeFile(a);
    make(m);
    assertOutput(m, fs().dir("b").file("B.class"));

    rebuild();
    assertOutput(m, fs().dir("b").file("B.class"));
  }

  public void testFileUnderIgnoredFolder() {
    VirtualFile src = createFile("src/A.java", "class A{}").getParent();
    Module m = addModule("m", src);
    make(m);
    assertOutput(m, fs().file("A.class"));

    VirtualFile b = createFile("src/CVS/B.java", "package CVS; class B{}");
    make(m);
    assertOutput(m, fs().file("A.class"));

    changeFile(b);
    make(m);
    assertOutput(m, fs().file("A.class"));

    rebuild();
    assertOutput(m, fs().file("A.class"));
  }
}

@@ -210,16 +210,38 @@
 tUtil;%0A%0A
+import java.io.File;%0A%0A
 import s
@@ -293,16 +293,16 @@
 der.fs;%0A
-
 %0A/**%0A * 
@@ -1462,32 +1462,1194 @@
 pToDate();%0A  %7D%0A%0A
+  public void testForceCompileUpToDateFileAndDoNotCompileResources() %7B%0A    VirtualFile a = createFile(%22src/A.java%22, %22class A%7B%7D%22);%0A    VirtualFile res = createFile(%22src/res.properties%22, %22aaa=bbb%22);%0A    Module module = addModule(%22a%22, a.getParent());%0A    make(module);%0A    assertOutput(module, fs().file(%22A.class%22).file(%22res.properties%22));%0A    final VirtualFile output = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(getOutputDir(module));%0A    assertNotNull(output);%0A    final VirtualFile classFile = output.findChild(%22A.class%22);%0A    assertNotNull(classFile);%0A    final VirtualFile resOutputFile = output.findChild(%22res.properties%22);%0A    assertNotNull(resOutputFile);%0A    final File resourceOutputIoFile = new File(resOutputFile.getPath());%0A    final long resStampBefore = resourceOutputIoFile.lastModified();%0A    deleteFile(classFile);%0A    make(module);%0A    assertOutput(module, fs().file(%22res.properties%22));%0A    compile(true, a);%0A    assertOutput(module, fs().file(%22A.class%22).file(%22res.properties%22));%0A    final long resStampAfter = resourceOutputIoFile.lastModified();%0A    assertEquals(resStampBefore, resStampAfter);%0A    assertModulesUpToDate();%0A  %7D%0A%0A
   public void te
@@ -3816,178 +3816,30 @@
     
-boolean upToDate = getCompilerManager().isUpToDate(getCompilerManager().createProjectCompileScope(myProject));%0A    assertFalse(%22Module should not be up to date%22, u
+assertModulesU
 pToDate
+(
 );%0A 

fix deleting module resources on forcing single java file compilation