package com.bluepapa32.gradle.plugins.watch;

import java.io.PrintStream;
import java.util.List;

import org.gradle.api.Project;
import org.gradle.api.logging.LogLevel;
import org.gradle.tooling.BuildLauncher;
import org.gradle.tooling.BuildException;
import org.gradle.tooling.GradleConnectionException;
import org.gradle.tooling.GradleConnector;
import org.gradle.tooling.ProgressEvent;
import org.gradle.tooling.ProgressListener;
import org.gradle.tooling.ProjectConnection;
import org.gradle.tooling.ResultHandler;

import static org.gradle.api.logging.LogLevel.INFO;

public class WatchTargetTaskRunner implements AutoCloseable {

    private ProjectConnection connection;

    public WatchTargetTaskRunner(Project project) {

        final PrintStream out = System.out;

        LogLevel logLevel = project.getGradle().getStartParameter().getLogLevel();
        if (INFO.compareTo(logLevel) < 0) {
            System.setOut(new DevNullPrintStream());
        }

        out.print("Starting");
        out.flush();

        connection = GradleConnector.newConnector()
                .useInstallation(project.getGradle().getGradleHomeDir())
                .forProjectDirectory(project.getProjectDir())
                .connect();

        connection
            .newBuild()
            .withArguments("-q")
            .addProgressListener(new ProgressListener() {
                public void statusChanged(ProgressEvent event) {
                    out.print("..");
                    out.flush();
                }
            })
            .run(new ResultHandler<Void>() {
                public void onComplete(Void result) {
                    System.setOut(out);
                    out.println(" OK");
                }
                public void onFailure(GradleConnectionException failure) {
                }
            });
    }

    public void run(List<WatchTarget> targets) {

        if (targets == null || targets.isEmpty()) {
            return;
        }

        BuildLauncher launcher = connection.newBuild();

        for (WatchTarget target : targets) {
            launcher.forTasks(target.getTasks().toArray(new String[0]));
        }

        final int[] taskNum = new int[1];

        launcher.addProgressListener(new ProgressListener() {
            public void statusChanged(ProgressEvent event) {
                if ("Execute tasks".equals(event.getDescription())) {
                    taskNum[0]++;
                }
            }
        });

        long timestamp = System.currentTimeMillis();

        try {

            launcher.run();

        } catch (BuildException e) {
            // ignore...
        }

        for (WatchTarget target : targets) {
            target.setExecutedAt(timestamp);
        }
    }

    public void close() {
        connection.close();
    }
}

@@ -94,38 +94,224 @@
 st;%0A
-%0Aimport org.gradle.api.Project
+import java.util.Arrays;%0Aimport java.util.ArrayList;%0Aimport java.util.Map;%0A%0Aimport org.gradle.StartParameter;%0Aimport org.gradle.api.Project;%0Aimport org.gradle.api.logging.Logger;%0Aimport org.gradle.api.logging.Logging
 ;%0Aim
@@ -831,90 +831,453 @@
 ate 
-ProjectConnection connection;%0A%0A    public WatchTargetTaskRunner(Project project) %7B
+static final Logger LOG = Logging.getLogger(WatchTargetTaskRunner.class);%0A%0A    private String%5B%5D arguments;%0A%0A    private ProjectConnection connection;%0A%0A    public WatchTargetTaskRunner(Project project) %7B%0A%0A        StartParameter parameter = project.getGradle().getStartParameter();%0A%0A        this.arguments = getArguments(parameter);%0A%0A        if (LOG.isDebugEnabled()) %7B%0A            LOG.debug(%22Arguments: %7B%7D%22, Arrays.toString(arguments));%0A        %7D
 %0A%0A  
@@ -1352,44 +1352,16 @@
  = p
-roject.getGradle().getStartP
 arameter
 ().g
@@ -1356,18 +1356,16 @@
 arameter
-()
 .getLogL
@@ -2540,26 +2540,125 @@
 nnection
-.newBuild(
+%0A                                    .newBuild()%0A                                    .withArguments(arguments
 );%0A%0A    
@@ -3435,10 +3435,343 @@
 ;%0A    %7D%0A
+%0A    private String%5B%5D getArguments(StartParameter parameter) %7B%0A        List%3CString%3E args = new ArrayList%3C%3E();%0A        for (Map.Entry%3CString, String%3E e : parameter.getProjectProperties().entrySet()) %7B%0A            args.add(%22-P%22 + e.getKey() + %22=%22 + e.getValue());%0A        %7D%0A        return args.toArray(new String%5Bargs.size()%5D);%0A    %7D%0A%0A
 %7D%0A

fix #11