package org.sugarj.common;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
import org.sugarj.common.path.Path;
import org.sugarj.common.path.RelativePath;

/**
 * 
 * Provides methods related to processing Java. Mainly, we provide
 * a method for compiling Java code.
 * 
 * @author Sebastian Erdweg <seba at informatik uni-marburg de>
 *
 */
public class JavaCommands {

  public static boolean javac(Path sourceFile, Path dir, Collection<Path> cp) throws IOException {
    ArrayList<Path> sourceFiles = new ArrayList<Path>();
    sourceFiles.add(sourceFile);
    return javac(sourceFiles, dir, cp);
  }
  
  public static boolean javac(List<Path> sourceFiles, Path dir, Collection<Path> cp) throws IOException {
    return javac(sourceFiles, dir, cp.toArray(new Path[cp.size()]));
  }

  public static boolean javac(List<Path> sourceFiles, Path dir, Path... cp) throws IOException {
    StringBuilder cpBuilder = new StringBuilder();
    
    for (int i = 0; i < cp.length; i++) {
      cpBuilder.append(FileCommands.toWindowsPath(cp[i].getAbsolutePath()));
      
      if (i < cp.length - 1)
        cpBuilder.append(Environment.classpathsep);
    }
    
    if(cp.length > 0)
      cpBuilder.append(Environment.classpathsep);
    
    cpBuilder.append(dir);
    

    String[] cmd = new String[7 + sourceFiles.size()];
    cmd[0] = "-cp";
    cmd[1] = cpBuilder.toString();
    cmd[2] = "-d";
    cmd[3] = FileCommands.toWindowsPath(dir.getAbsolutePath());
    cmd[4] = "-source";
    cmd[5] = "1.5";
    cmd[6] = "-nowarn";
    
    for (int i = 0; i < sourceFiles.size(); i++)
      cmd[i + 7] = FileCommands.toWindowsPath(sourceFiles.get(i).getAbsolutePath());
    
    // this is ECJ
    return BatchCompiler.compile(
        cmd,
        new PrintWriter(Log.out),
        new PrintWriter(Log.err),
        null);
  }

  /**
   * Runs a compiled java program, linking against  {@code strategoxt.jar},
   * and providing a bunch of parameters. 
   */
  public static void java(Path dir, String main, Collection<String> paths, String... args) throws IOException {
    StringBuilder classpath = new StringBuilder();
    classpath.append(FileCommands.toWindowsPath(dir.getAbsolutePath()));
    classpath.append(Environment.classpathsep);
    
    for (String path : paths)
      classpath.append(path).append(Environment.classpathsep);
    
    String[] cmd = new String[args.length + 5];
    cmd[0] = "java";
    cmd[1] = "-Xss4M";
    cmd[2] = "-cp";
    cmd[3] = classpath.toString();
    cmd[4] = main;
    
    for (int i = 0; i < args.length; i++)
      cmd[i + 5] = args[i];
    
    new CommandExecution(true).executeWithPrefix(main, cmd);
  }
  
  
  public static void jar(Path dir, Path output) {
    String[] cmd = {
        "jar",
        "cf",
        output.getAbsolutePath(),
        "-C", dir.getAbsolutePath(),
        "."
        };
    
    new CommandExecution(true).execute(cmd);
  }
  
}

@@ -155,109 +155,11 @@
 til.
-HashSet;%0Aimport java.util.List;%0Aimport java.util.Map;%0Aimport java.util.Map.Entry;%0Aimport java.util.Se
+Lis
 t;%0A%0A
@@ -255,52 +255,8 @@
 ath;
-%0Aimport org.sugarj.common.path.RelativePath;
 %0A%0A/*
@@ -832,32 +832,38 @@
 vac(sourceFiles,
+ null,
  dir, cp.toArray
@@ -936,32 +936,258 @@
 th%3E sourceFiles,
+ Path sourcePath, Path dir, Collection%3CPath%3E cp) throws IOException %7B%0A    return javac(sourceFiles, sourcePath, dir, cp.toArray(new Path%5Bcp.size()%5D));%0A  %7D%0A%0A  public static boolean javac(List%3CPath%3E sourceFiles, Path sourcePath,
  Path dir, Path.
@@ -1598,16 +1598,85 @@
 ;%0A    %0A%0A
+    int argNum = 7 + (sourcePath == null ? 0 : 2);%0A    int next = 0;%0A
     Stri
@@ -1697,17 +1697,22 @@
  String%5B
-7
+argNum
  + sourc
@@ -1731,25 +1731,30 @@
 )%5D;%0A    cmd%5B
-0
+next++
 %5D = %22-cp%22;%0A 
@@ -1756,25 +1756,30 @@
 p%22;%0A    cmd%5B
-1
+next++
 %5D = cpBuilde
@@ -1796,25 +1796,30 @@
 ();%0A    cmd%5B
-2
+next++
 %5D = %22-d%22;%0A  
@@ -1820,25 +1820,30 @@
 d%22;%0A    cmd%5B
-3
+next++
 %5D = FileComm
@@ -1889,25 +1889,30 @@
 ));%0A    cmd%5B
-4
+next++
 %5D = %22-source
@@ -1922,17 +1922,22 @@
     cmd%5B
-5
+next++
 %5D = %221.5
@@ -1951,9 +1951,14 @@
 cmd%5B
-6
+next++
 %5D = 
@@ -1968,16 +1968,149 @@
 owarn%22;%0A
+    if (sourcePath != null) %7B%0A      cmd%5Bnext++%5D = %22-sourcepath%22;%0A      cmd%5Bnext++%5D = sourcePath.getAbsolutePath();%0A    %7D%0A      %0A    %0A
     %0A   
@@ -2169,17 +2169,22 @@
 cmd%5Bi + 
-7
+argNum
 %5D = File

allow Java files to resolve implicitly withing package