/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jetbrains.idea.maven.compiler;

import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerConfigurationImpl;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.compiler.options.ExcludeEntryDescription;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PsiTestUtil;

import java.io.File;

public class ResourceCopyingTest extends MavenCompilingTestCase {

  @Override
  protected void setUpInWriteAction() throws Exception {
    super.setUpInWriteAction();

    CompilerConfiguration.getInstance(myProject).addResourceFilePattern("!*.xxx");
    CompilerConfiguration.getInstance(myProject).addResourceFilePattern("!*.yyy");
    CompilerConfiguration.getInstance(myProject).addResourceFilePattern("!*.zzz");
  }

  public void testBasic() throws Exception {
    createProjectSubFile("src/main/resources/dir/file.properties");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>");
    compileModules("project");

    assertCopied("target/classes/dir/file.properties");
  }

  public void testCustomResources() throws Exception {
    createProjectSubFile("res/dir1/file1.properties");
    createProjectSubFile("testRes/dir2/file2.properties");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource><directory>res</directory></resource>" +
                  "  </resources>" +
                  "  <testResources>" +
                  "    <testResource><directory>testRes</directory></testResource>" +
                  "  </testResources>" +
                  "</build>");

    compileModules("project");

    assertCopied("target/classes/dir1/file1.properties");
    assertCopied("target/test-classes/dir2/file2.properties");
  }

  public void testCustomTargetPath() throws Exception {
    createProjectSubFile("res/dir/file.properties");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "      <targetPath>foo</targetPath>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");
    assertCopied("target/classes/foo/dir/file.properties");
  }

  public void testResourcesPluginCustomTargetPath() throws Exception {
    createProjectSubFile("res/dir/file.properties");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <plugins>" +
                  "    <plugin>" +
                  "      <artifactId>maven-resources-plugin</artifactId>" +
                  "      <version>2.6</version>" +
                  "      <configuration>" +
                  "        <outputDirectory>${basedir}/target/resourceOutput</outputDirectory>" +
                  "      </configuration>" +
                  "    </plugin>" +
                  "  </plugins>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "      <targetPath>foo</targetPath>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");
    assertCopied("target/resourceOutput/foo/dir/file.properties");
  }

  public void testAbsoluteCustomTargetPath() throws Exception {
    createProjectSubFile("res/foo/file.properties");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "      <targetPath>${build.directory}/anotherDir</targetPath>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");
    assertCopied("target/anotherDir/foo/file.properties");
  }

  public void testMavenSpecifiedPattern() throws Exception {
    createProjectSubFile("res/subdir/a.txt");
    createProjectSubFile("res/b.txt");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "      <includes>" +
                  "        <include>**/**</include>" +
                  "      </includes>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");

    assertCopied("target/classes/subdir/a.txt");
    assertCopied("target/classes/b.txt");
  }

  public void testMavenSpecifiedPatternEndSlash() throws Exception {
    createProjectSubFile("res/subdir/a.txt");
    createProjectSubFile("res/b.txt");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "      <includes>" +
                  "        <include>**/</include>" +
                  "      </includes>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");

    assertCopied("target/classes/subdir/a.txt");
    assertCopied("target/classes/b.txt");
  }

  public void testIncludesAndExcludes() throws Exception {
    createProjectSubFile("res/dir/file.xxx");
    createProjectSubFile("res/dir/file.yyy");
    createProjectSubFile("res/file.xxx");
    createProjectSubFile("res/file.yyy");
    createProjectSubFile("res/file.zzz");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "      <includes>" +
                  "        <include>**/*.xxx</include>" +
                  "        <include>**/*.yyy</include>" +
                  "      </includes>" +
                  "      <excludes>" +
                  "        <exclude>*.xxx</exclude>" +
                  "        <exclude>dir/*.yyy</exclude>" +
                  "      </excludes>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");

    assertCopied("target/classes/dir/file.xxx");
    assertNotCopied("target/classes/dir/file.yyy");
    assertNotCopied("target/classes/file.xxx");
    assertCopied("target/classes/file.yyy");
    assertNotCopied("target/classes/file.zzz");
  }

  public void testDoNotCopyIgnoredFiles() throws Exception {
    createProjectSubFile("res/CVS/file.properties");
    createProjectSubFile("res/.svn/file.properties");
    createProjectSubFile("res/zzz/file.properties");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "      <includes>" +
                  "        <include>**/*.properties</include>" +
                  "      </includes>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");

    assertNotCopied("target/classes/CVS");
    assertNotCopied("target/classes/.svn");
    assertCopied("target/classes/zzz/file.properties");
  }

  public void testDeletingFilesThatWasCopiedAndThenDeleted() throws Exception {
    final VirtualFile file = createProjectSubFile("res/file.properties");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");
    assertCopied("target/classes/file.properties");

    new WriteCommandAction.Simple(myProject) {
      @Override
      protected void run() throws Throwable {
        file.delete(this);
      }
    }.execute().throwException();

    compileModules("project");
    assertNotCopied("target/classes/file.properties");
  }

  public void testDeletingFilesThatWasCopiedAndThenExcluded() throws Exception {
    createProjectSubFile("res/file.properties");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");
    assertCopied("target/classes/file.properties");

    createProjectPom("<groupId>test</groupId>" +
                     "<artifactId>project</artifactId>" +
                     "<version>1</version>" +

                     "<build>" +
                     "  <resources>" +
                     "    <resource>" +
                     "      <directory>res</directory>" +
                     "      <excludes>" +
                     "        <exclude>**/*</exclude>" +
                     "      </excludes>" +
                     "    </resource>" +
                     "  </resources>" +
                     "</build>");
    importProject();

    compileModules("project");
    assertNotCopied("target/classes/file.properties");
  }

  public void testDoNotCopyExcludedStandardResources() throws Exception {

    CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
    configuration.addResourceFilePattern("*.zzz");

    createProjectSubFile("res/file.xxx");
    createProjectSubFile("res/file.zzz");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +

                  "<build>" +
                  "  <resources>" +
                  "    <resource>" +
                  "      <directory>res</directory>" +
                  "      <includes>" +
                  "        <include>**/*.xxx</include>" +
                  "      </includes>" +
                  "      <excludes>" +
                  "        <exclude>**/*.zzz</exclude>" +
                  "      </excludes>" +
                  "    </resource>" +
                  "  </resources>" +
                  "</build>");

    compileModules("project");
    assertCopied("target/classes/file.xxx");
    assertNotCopied("target/classes/file.zzz");
  }

  public void testDoNotDeleteFilesFromOtherModulesOutput() throws Exception {
    createProjectSubFile("m1/resources/file.xxx");
    createProjectSubFile("m2/resources/file.yyy");

    createProjectPom("<groupId>test</groupId>" +
                     "<artifactId>project</artifactId>" +
                     "<version>1</version>" +

                     "<modules>" +
                     "  <module>m1</module>" +
                     "  <module>m2</module>" +
                     "</modules>");

    createModulePom("m1",
                    "<groupId>test</groupId>" +
                    "<artifactId>m1</artifactId>" +
                    "<version>1</version>" +

                    "<build>" +
                    "  <resources>" +
                    "    <resource>" +
                    "      <directory>resources</directory>" +
                    "    </resource>" +
                    "  </resources>" +
                    "</build>");

    createModulePom("m2",
                    "<groupId>test</groupId>" +
                    "<artifactId>m2</artifactId>" +
                    "<version>1</version>" +

                    "<build>" +
                    "  <resources>" +
                    "    <resource>" +
                    "      <directory>resources</directory>" +
                    "    </resource>" +
                    "  </resources>" +
                    "</build>");
    importProject();

    compileModules("project", "m1", "m2");
    assertCopied("m1/target/classes/file.xxx");
    assertCopied("m2/target/classes/file.yyy");

    compileModules("m1");
    assertCopied("m1/target/classes/file.xxx");
    assertCopied("m2/target/classes/file.yyy");

    compileModules("m2");
    assertCopied("m1/target/classes/file.xxx");
    assertCopied("m2/target/classes/file.yyy");

    compileModules("project");
    assertCopied("m1/target/classes/file.xxx");
    assertCopied("m2/target/classes/file.yyy");
  }

  public void testDoNotDeleteFilesFromOtherModulesOutputWhenOutputIsTheSame() throws Exception {
    createProjectSubFile("resources/file.xxx");

    createProjectPom("<groupId>test</groupId>" +
                     "<artifactId>project</artifactId>" +
                     "<version>1</version>" +

                     "<modules>" +
                     "  <module>m1</module>" +
                     "  <module>m2</module>" +
                     "</modules>");

    createModulePom("m1",
                    "<groupId>test</groupId>" +
                    "<artifactId>m1</artifactId>" +
                    "<version>1</version>" +

                    "<build>" +
                    "  <resources>" +
                    "    <resource>" +
                    "      <directory>../resources</directory>" +
                    "    </resource>" +
                    "  </resources>" +
                    "</build>");

    createModulePom("m2",
                    "<groupId>test</groupId>" +
                    "<artifactId>m2</artifactId>" +
                    "<version>1</version>" +

                    "<build>" +
                    "  <resources>" +
                    "    <resource>" +
                    "      <directory>../resources</directory>" +
                    "    </resource>" +
                    "  </resources>" +
                    "</build>");
    importProject();

    new WriteCommandAction.Simple(myProject) {
      @Override
      protected void run() throws Throwable {
        setModulesOutput(myProjectRoot.createChildDirectory(this, "output"), "project", "m1", "m2");
      }
    }.execute().throwException();


    compileModules("project", "m1", "m2");
    assertCopied("output/file.xxx");

    compileModules("m1");
    assertCopied("output/file.xxx");

    compileModules("m2");
    assertCopied("output/file.xxx");

    compileModules("project");
    assertCopied("output/file.xxx");
  }

  private void setModulesOutput(final VirtualFile output, final String... moduleNames) {
    AccessToken accessToken = WriteAction.start();
    try {
      for (String each : moduleNames) {
        PsiTestUtil.setCompilerOutputPath(getModule(each), output.getUrl(), false);
        PsiTestUtil.setCompilerOutputPath(getModule(each), output.getUrl(), true);
      }
    }
    finally {
      accessToken.finish();
    }
  }

  public void testWebResources() throws Exception {
    if (ignore()) return;

    createProjectSubFile("res/dir/file.properties");
    createProjectSubFile("res/dir/file.xml");
    createProjectSubFile("res/file.properties");
    createProjectSubFile("res/file.xml");
    createProjectSubFile("res/file.txt");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>" +
                  "<packaging>war</packaging>" +

                  "<build>" +
                  "  <plugins>" +
                  "    <plugin>" +
                  "      <groupId>org.apache.maven.plugins</groupId>" +
                  "      <artifactId>maven-war-plugin</artifactId>" +
                  "      <configuration>" +
                  "        <webResources>" +
                  "          <directory>res</directory>" +
                  "          <includes>" +
                  "            <include>**/*.properties</include>" +
                  "            <include>**/*.xml</include>" +
                  "          </includes>" +
                  "          <excludes>" +
                  "            <exclude>*.properties</exclude>" +
                  "            <exclude>dir/*.xml</exclude>" +
                  "          </excludes>" +
                  "        </webResources>" +
                  "      </configuration>" +
                  "    </plugin>" +
                  "  </plugins>" +
                  "</build>");

    compileModules("project");

    assertCopied("target/classes/dir/file.properties");
    assertNotCopied("target/classes/dir/file.xml");
    assertNotCopied("target/classes/file.properties");
    assertCopied("target/classes/file.xml");
    assertNotCopied("target/classes/file.txt");
  }

  public void testOverridingWebResourceFilters() throws Exception {
    if (ignore()) return;

    createProjectPom("<groupId>test</groupId>" +
                     "<artifactId>project</artifactId>" +
                     "<version>1</version>" +
                     "<packaging>war</packaging>" +

                     "<build>" +
                     "  <plugins>" +
                     "    <plugin>" +
                     "      <groupId>org.apache.maven.plugins</groupId>" +
                     "      <artifactId>maven-war-plugin</artifactId>" +
                     "      <configuration>\n" +
                     "        <!-- the default value is the filter list under build -->\n" +
                     "        <!-- specifying a filter will override the filter list under build -->\n" +
                     "        <filters>\n" +
                     "          <filter>properties/config.prop</filter>\n" +
                     "        </filters>\n" +
                     "        <nonFilteredFileExtensions>\n" +
                     "          <!-- default value contains jpg,jpeg,gif,bmp,png -->\n" +
                     "          <nonFilteredFileExtension>pdf</nonFilteredFileExtensions>\n" +
                     "        </nonFilteredFileExtensions>\n" +
                     "        <webResources>\n" +
                     "          <resource>\n" +
                     "            <directory>resource2</directory>\n" +
                     "            <!-- it's not a good idea to filter binary files -->\n" +
                     "            <filtering>false</filtering>\n" +
                     "          </resource>\n" +
                     "          <resource>\n" +
                     "            <directory>configurations</directory>\n" +
                     "            <!-- enable filtering -->\n" +
                     "            <filtering>true</filtering>\n" +
                     "            <excludes>\n" +
                     "              <exclude>**/properties</exclude>\n" +
                     "            </excludes>\n" +
                     "          </resource>\n" +
                     "        </webResources>\n" +
                     "      </configuration>" +
                     "    </plugin>" +
                     "  </plugins>" +
                     "</build>");
  }

  public void testCopingNonMavenResources() throws Exception {
    if (ignore()) return;

    createProjectSubFile("src/resources/a.txt", "a");

    VirtualFile configDir = createProjectSubDir("src/config");
    createProjectSubFile("src/config/b.txt", "b");
    createProjectSubFile("src/config/JavaClass.java", "class JavaClass {}");
    createProjectSubFile("src/config/xxx.xxx", "xxx"); // *.xxx is excluded from resource coping, see setUpInWriteAction()

    final VirtualFile excludedDir = createProjectSubDir("src/excluded");
    createProjectSubFile("src/excluded/c.txt", "c");

    importProject("<groupId>test</groupId>" +
                  "<artifactId>project</artifactId>" +
                  "<version>1</version>");

    Module module = ModuleManager.getInstance(myProject).findModuleByName("project");
    PsiTestUtil.addSourceRoot(module, configDir);
    PsiTestUtil.addSourceRoot(module, excludedDir);

    new WriteCommandAction.Simple(myProject) {
      @Override
      protected void run() throws Throwable {
        CompilerConfiguration.getInstance(myProject).getExcludedEntriesConfiguration()
          .addExcludeEntryDescription(new ExcludeEntryDescription(excludedDir, true, false, getTestRootDisposable()));

        setModulesOutput(myProjectRoot.createChildDirectory(this, "output"), "project", "m1", "m2");
      }
    }.execute().throwException();

    compileModules("project");

    assertCopied("output/a.txt");
    assertCopied("output/b.txt");

    assertNotCopied("output/JavaClass.java");
    assertNotCopied("output/xxx.xxx");
    assertNotCopied("output/c.txt");
  }

  private void assertCopied(String path) {
    assertTrue(new File(myProjectPom.getParent().getPath(), path).exists());
  }

  private void assertNotCopied(String path) {
    assertFalse(new File(myProjectPom.getParent().getPath(), path).exists());
  }
}
