package inlein.client.tasks;

import inlein.client.*;
import inlein.client.signals.Registerer;
import java.nio.file.*;
import java.util.*;

public final class Run extends Task {

    public static final Run instance = new Run();

    private Run() {
        super("--run",
              "Runs a clojure script with dependencies",
              "Runs a clojure script with dependencies");
    }

    @SuppressWarnings("unchecked")
    public void run(ServerConnection conn, String[] args) throws Exception {
        if (args.length == 0) {
            System.out.println("run expects at least 1 argument -- the file to run");
            System.exit(1);
        }
        conn = ServerConnection.ensureConnected(conn);
        Map<String, Object> req = new HashMap<String, Object>();
        req.put("op", "jvm-opts");
        Path p = Paths.get(args[0]).toAbsolutePath();
        req.put("file", p.toString());
        Map<String, Object> reply = conn.sendRequest(req);

        String javaCmd = System.getenv("JAVA_CMD");
        if (javaCmd == null) {
            javaCmd = "java";
        }
        ArrayList<String> cmdArgs = new ArrayList<String>();
        cmdArgs.add(javaCmd);
        cmdArgs.addAll((List<String>) reply.get("jvm-opts"));
        cmdArgs.add(String.format("-D$0=%s", args[0]));
        cmdArgs.add("clojure.main");
        for (String arg : args) {
            cmdArgs.add(arg);
        }
        ProcessBuilder pb = new ProcessBuilder(cmdArgs);
        pb.inheritIO();
        Process proc = pb.start();
        Runtime.getRuntime().addShutdownHook(new Thread(new ProcessKiller(proc)));
        Registerer.dropSignals();
        proc.waitFor();
        System.exit(proc.exitValue());
    }

    private static class ProcessKiller implements Runnable {
        final Process proc;
        ProcessKiller(Process proc) {
            this.proc = proc;
        }

        public void run() {
            proc.destroy();
        }
    }
}

@@ -104,20 +104,67 @@
 ava.nio.
-file
+channels.*;%0Aimport java.nio.file.*;%0Aimport java.nio
 .*;%0Aimpo
@@ -910,16 +910,28 @@
 tePath()
+.normalize()
 ;%0A      
@@ -1019,24 +1019,586 @@
 uest(req);%0A%0A
+        String file = null;%0A        List%3CString%3E fileList = (List%3CString%3E) reply.get(%22files%22);%0A        if (fileList.size() == 1) %7B%0A            file = fileList.get(0); // == args%5B0%5D%0A        %7D else %7B%0A            Path tmp = Files.createTempFile(%22inlein-file%22, %22.clj%22);%0A            try (FileChannel out = FileChannel.open(tmp, StandardOpenOption.WRITE)) %7B%0A                for (String srcFile : fileList) %7B%0A                    append(out, Paths.get(srcFile));%0A                %7D%0A            %7D%0A            file = tmp.toAbsolutePath().normalize().toString();%0A        %7D%0A%0A
         Stri
@@ -1966,30 +1966,71 @@
     
-for (String arg : args
+cmdArgs.add(file);%0A        for (int i = 1; i %3C args.length; i++
 ) %7B%0A
@@ -2056,16 +2056,20 @@
 .add(arg
+s%5Bi%5D
 );%0A     
@@ -2610,16 +2610,604 @@
       %7D%0A
-
     %7D
+%0A%0A    private static void append(FileChannel dst, Path src) throws Exception %7B%0A        ByteBuffer bb = ByteBuffer.wrap(lineSep.getBytes());%0A        dst.write(bb);%0A        try (FileChannel srcCh = FileChannel.open(src, StandardOpenOption.READ)) %7B%0A            long srcSize = srcCh.size();%0A            long transferred = srcCh.transferTo(0, srcSize, dst);%0A            while(transferred != srcSize)%7B%0A                transferred += srcCh.transferTo(transferred, srcSize - transferred, dst);%0A            %7D%0A        %7D%0A    %7D%0A%0A    final static String lineSep = System.getProperty(%22line.separator%22);
 %0A%7D%0A

Implement :file-deps for run command