package org.jenkinsci.plugins.workflow.cps;

import com.cloudbees.groovy.cps.Outcome;
import groovy.lang.Closure;
import org.jenkinsci.plugins.workflow.cps.persistence.PersistIn;

import java.util.HashMap;
import java.util.Map;

import static org.jenkinsci.plugins.workflow.cps.persistence.PersistenceContext.*;

/**
 * "Built-in" functions for CPS groovy script.
 *
 * These static methods get auto-imported into the script during compilation.
 *
 * @author Kohsuke Kawaguchi
 */
@PersistIn(NONE)
public class CpsBuiltinSteps {
    /**
     * Executes a shell script in the current workspace.
     */
    public static int sh(Object... args) {
        return (Integer)dsl().invokeMethod("sh", asArray(args));
    }

    /**
     * Executes the body closure up to N times until it succeeds.
     *
     * <pre>
     * retry (3) {
     *     ... computation that can fail ...
     * }
     * </pre>
     */
    public static void retry(int n, Closure body) {
        dsl().invokeMethod("retry", asArray(n, body));
    }

    public static Map<String,Outcome> parallel(Map<String,Closure> subflows) {
        return (Map<String,Outcome>)dsl().invokeMethod("parallel", asArray(subflows));
    }

    /**
     * Version of {@code parallel} that doesn't have any branch names.
     *
     * The lack of branch name hurts visualization, so it's preferrable to give them if you can.
     */
    public static Map<String,Outcome> parallel(Closure... subflows) {
        Map<String,Closure> flows = new HashMap<String, Closure>();
        for (int i=0; i<subflows.length; i++)
            flows.put("flow"+(i+1),subflows[i]);
        return parallel(flows);
    }

    private static DSL dsl() {
        return new DSL(CpsThread.current().getExecution().getOwner());
    }

    private static Object[] asArray(Object... args) {
        return args;
    }
}

@@ -173,16 +173,70 @@
 istIn;%0A%0A
+import java.util.Arrays;%0Aimport java.util.Collection;%0A
 import j
@@ -1493,32 +1493,178 @@
 ... subflows) %7B%0A
+        return parallel(Arrays.asList(subflows));%0A    %7D%0A%0A    public static Map%3CString,Outcome%3E parallel(Collection%3C? extends Closure%3E subflows) %7B%0A
         Map%3CStri
@@ -1727,45 +1727,53 @@
     
-for (
 int i=
-0; i%3Csubflows.length; i++)
+1;%0A        for (Closure c : subflows) %7B
 %0A   
@@ -1805,24 +1805,24 @@
 +(i+
-1),subflows%5Bi%5D);
++),c);%0A        %7D
 %0A   

Handle collection as well