/*
 * Copyright 2000-2014 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 com.intellij.compiler.ant;

import com.intellij.compiler.ant.taskdefs.*;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NonNls;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Eugene Zhuravlev
 *         Date: Mar 19, 2004
 */
public class CompileModuleChunkTarget extends CompositeGenerator {

  public CompileModuleChunkTarget(final Project project,
                                  ModuleChunk moduleChunk,
                                  VirtualFile[] sourceRoots,
                                  VirtualFile[] testSourceRoots,
                                  File baseDir,
                                  GenerationOptions genOptions) {
    final String moduleChunkName = moduleChunk.getName();
    //noinspection HardCodedStringLiteral
    final Tag compilerArgs = new Tag("compilerarg", Couple.of("line", BuildProperties.propertyRef(
      BuildProperties.getModuleChunkCompilerArgsProperty(moduleChunkName))));
    //noinspection HardCodedStringLiteral
    final Couple<String> classpathRef = Couple.of("refid", BuildProperties.getClasspathProperty(moduleChunkName));
    final Tag classpathTag = new Tag("classpath", classpathRef);
    //noinspection HardCodedStringLiteral
    final Tag bootclasspathTag =
      new Tag("bootclasspath", Couple.of("refid", BuildProperties.getBootClasspathProperty(moduleChunkName)));
    final PatternSetRef compilerExcludes = new PatternSetRef(BuildProperties.getExcludedFromCompilationProperty(moduleChunkName));

    final String mainTargetName = BuildProperties.getCompileTargetName(moduleChunkName);
    final @NonNls String productionTargetName = mainTargetName + ".production";
    final @NonNls String testsTargetName = mainTargetName + ".tests";

    final ChunkCustomCompilerExtension[] customCompilers = moduleChunk.getCustomCompilers();
    final String customCompilersDependency = customCompilers.length != 0 || genOptions.enableFormCompiler ?
                                             BuildProperties.TARGET_REGISTER_CUSTOM_COMPILERS : "";
    final int modulesCount = moduleChunk.getModules().length;
    Target mainTarget = new Target(mainTargetName, productionTargetName + "," + testsTargetName,
                                   CompilerBundle.message("generated.ant.build.compile.modules.main.target.comment", modulesCount,
                                                          moduleChunkName), null);
    String dependenciesProduction = getChunkDependenciesString(moduleChunk);
    if (customCompilersDependency.length() > 0) {
      if (dependenciesProduction != null && dependenciesProduction.length() > 0) {
        dependenciesProduction = customCompilersDependency + "," + dependenciesProduction;
      }
      else {
        dependenciesProduction = customCompilersDependency;
      }
    }
    Target productionTarget = new Target(productionTargetName, dependenciesProduction,
                                         CompilerBundle.message("generated.ant.build.compile.modules.production.classes.target.comment",
                                                                modulesCount, moduleChunkName), null);
    String dependenciesTests = (customCompilersDependency.length() != 0 ? customCompilersDependency + "," : "") + productionTargetName;
    Target testsTarget = new Target(testsTargetName, dependenciesTests,
                                    CompilerBundle.message("generated.ant.build.compile.modules.tests.target.comment", modulesCount,
                                                           moduleChunkName), BuildProperties.PROPERTY_SKIP_TESTS);

    if (sourceRoots.length > 0) {
      final String outputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(moduleChunkName));
      final Tag srcTag = new Tag("src", Couple.of("refid", BuildProperties.getSourcepathProperty(moduleChunkName)));
      productionTarget.add(new Mkdir(outputPathRef));
      createCustomCompilerTasks(project, moduleChunk, genOptions, false, customCompilers, compilerArgs, bootclasspathTag,
                                classpathTag, compilerExcludes, srcTag, outputPathRef, productionTarget);
      if (customCompilers.length == 0 || genOptions.enableFormCompiler) {
        final Javac javac = new Javac(genOptions, moduleChunk, outputPathRef);
        javac.add(compilerArgs);
        javac.add(bootclasspathTag);
        javac.add(classpathTag);
        javac.add(srcTag);
        javac.add(compilerExcludes);
        productionTarget.add(javac);
      }
      productionTarget.add(createCopyTask(project, moduleChunk, sourceRoots, outputPathRef, baseDir, genOptions));
    }

    if (testSourceRoots.length > 0) {

      final String testOutputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(moduleChunkName));
      final Tag srcTag = new Tag("src", Couple.of("refid", BuildProperties.getTestSourcepathProperty(moduleChunkName)));
      final Couple<String> testClasspathRef = Couple.of("refid", BuildProperties.getTestClasspathProperty(moduleChunkName));
      final Tag testClassPath = new Tag("classpath", testClasspathRef);
      testsTarget.add(new Mkdir(testOutputPathRef));
      createCustomCompilerTasks(project, moduleChunk, genOptions, true, customCompilers, compilerArgs, bootclasspathTag,
                                testClassPath, compilerExcludes, srcTag, testOutputPathRef, testsTarget);
      if (customCompilers.length == 0 || genOptions.enableFormCompiler) {
        final Javac javac = new Javac(genOptions, moduleChunk, testOutputPathRef);
        javac.add(compilerArgs);
        javac.add(bootclasspathTag);
        javac.add(testClassPath);
        javac.add(srcTag);
        javac.add(compilerExcludes);
        testsTarget.add(javac);
      }
      testsTarget.add(createCopyTask(project, moduleChunk, testSourceRoots, testOutputPathRef, baseDir, genOptions));
    }

    add(mainTarget);
    add(productionTarget, 1);
    add(testsTarget, 1);
  }

  /**
   * Create custom compiler tasks
   *
   * @param project          the project
   * @param moduleChunk      the module chunk
   * @param genOptions       generation options
   * @param compileTests     if true tests are being compiled
   * @param customCompilers  an array of custom compilers for this chunk
   * @param compilerArgs     the javac compiler arguments
   * @param bootclasspathTag the boot classpath element for the javac compiler
   * @param classpathTag     the classpath tag for the javac compiler
   * @param compilerExcludes the compiler excluded tag
   * @param srcTag           the source tag
   * @param outputPathRef    the output path references
   * @param target           the target where to add custom compiler
   */
  private static void createCustomCompilerTasks(Project project,
                                                ModuleChunk moduleChunk,
                                                GenerationOptions genOptions,
                                                boolean compileTests,
                                                ChunkCustomCompilerExtension[] customCompilers,
                                                Tag compilerArgs,
                                                Tag bootclasspathTag,
                                                Tag classpathTag,
                                                PatternSetRef compilerExcludes,
                                                Tag srcTag,
                                                String outputPathRef,
                                                Target target) {
    if (customCompilers.length > 1) {
      target.add(new Tag("fail", Couple.of("message", CompilerBundle.message(
        "generated.ant.build.compile.modules.fail.custom.compilers"))));
    }
    for (ChunkCustomCompilerExtension ext : customCompilers) {
      ext.generateCustomCompile(project, moduleChunk, genOptions, compileTests, target, compilerArgs, bootclasspathTag,
                                classpathTag, compilerExcludes, srcTag, outputPathRef);
    }
  }

  private static String getChunkDependenciesString(ModuleChunk moduleChunk) {
    final StringBuffer moduleDependencies = new StringBuffer();
    final ModuleChunk[] dependencies = moduleChunk.getDependentChunks();
    for (int idx = 0; idx < dependencies.length; idx++) {
      final ModuleChunk dependency = dependencies[idx];
      if (idx > 0) {
        moduleDependencies.append(",");
      }
      moduleDependencies.append(BuildProperties.getCompileTargetName(dependency.getName()));
    }
    return moduleDependencies.toString();
  }

  private static Generator createCopyTask(final Project project,
                                          ModuleChunk chunk,
                                          VirtualFile[] sourceRoots,
                                          String toDir,
                                          File baseDir,
                                          final GenerationOptions genOptions) {
    //noinspection HardCodedStringLiteral
    final Tag filesSelector = new Tag("type", Couple.of("type", "file"));
    final PatternSetRef excludes = CompilerExcludes.isAvailable(project) ? new PatternSetRef(
      BuildProperties.getExcludedFromCompilationProperty(chunk.getName())) : null;
    final PatternSetRef resourcePatternsPatternSet = new PatternSetRef(BuildProperties.PROPERTY_COMPILER_RESOURCE_PATTERNS);
    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
    final CompositeGenerator composite = new CompositeGenerator();
    final Map<String, Copy> outputDirToTaskMap = new HashMap<String, Copy>();
    for (final VirtualFile root : sourceRoots) {
      final String packagePrefix = fileIndex.getPackageNameByDirectory(root);
      final String targetDir =
        packagePrefix != null && packagePrefix.length() > 0 ? toDir + "/" + packagePrefix.replace('.', '/') : toDir;
      Copy copy = outputDirToTaskMap.get(targetDir);
      if (copy == null) {
        copy = new Copy(targetDir);
        outputDirToTaskMap.put(targetDir, copy);
        composite.add(copy);
      }
      final FileSet fileSet = new FileSet(
        GenerationUtils.toRelativePath(root, baseDir, BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions));
      fileSet.add(resourcePatternsPatternSet);
      fileSet.add(filesSelector);
      if (excludes != null) {
        fileSet.add(excludes);
      }
      copy.add(fileSet);
    }
    return composite;
  }
}
