//----------------------------------------------------------------------
//This code is developed as part of the Java CoG Kit project
//The terms of the license can be found at http://www.cogkit.org/license
//This message may not be removed or altered.
//----------------------------------------------------------------------

/*
 * Created on Jul 13, 2012
 */
package org.griphyn.vdl.karajan.lib;

import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.globus.cog.karajan.arguments.Arg;
import org.globus.cog.karajan.stack.VariableNotFoundException;
import org.globus.cog.karajan.stack.VariableStack;
import org.globus.cog.karajan.util.ThreadingContext;
import org.globus.cog.karajan.workflow.ExecutionException;
import org.globus.cog.karajan.workflow.nodes.FlowNode;
import org.griphyn.vdl.karajan.WaitingThreadsMonitor;
import org.griphyn.vdl.mapping.DSHandle;

public class UnitStart extends FlowNode {
	public static final Logger uslogger = Logger.getLogger(UnitStart.class);
    // keep compatibility with log()
    public static final Logger logger = Logger.getLogger("swift");
    
    public static final Arg.Positional TYPE = new Arg.Positional("type");
    public static final Arg.Optional NAME = new Arg.Optional("name", null);
    public static final Arg.Optional LINE = new Arg.Optional("line", null);
    public static final Arg.Optional OUTPUTS = new Arg.Optional("outputs", null);
    
    @Override
    public void execute(VariableStack stack) throws ExecutionException {
        executeSimple(stack);
        complete(stack);
    }
    
    @Override
    public boolean isSimple() {
        return super.isSimple();
    }
    
    @Override
    public void executeSimple(VariableStack stack) throws ExecutionException {
        String type = (String) TYPE.getStatic(this);
        ThreadingContext thread = ThreadingContext.get(stack);
        String name = (String) NAME.getStatic(this);
        String line = (String) LINE.getStatic(this);
        
        log(true, type, thread, name, line);
        
        String outputs = (String) OUTPUTS.getStatic(this);
        if (outputs != null) {
            trackOutputs(stack, outputs, "SCOPE".equals(type));
        }
    }

    private void trackOutputs(VariableStack stack, String outputs, boolean deep) {
        String[] names = outputs.split(",");
        List<DSHandle> l = new LinkedList<DSHandle>();
        for (String name : names) {
        	if (deep) {
        	    try {
                    l.add((DSHandle) stack.getVar(name.toLowerCase()));
                }
                catch (VariableNotFoundException e) {
                    logger.info("Could not find variable " + name, e);
                }
        	}
        	else {
        		l.add((DSHandle) stack.parentFrame().getVar(name));
        	}
        }
        WaitingThreadsMonitor.addOutput(stack, l);
    }

    protected static void log(boolean start, String type, ThreadingContext thread, String name, String line) {
        if (type.equals("COMPOUND")) {
            logger.info((start ? "START" : "END") + type + " thread=" + thread + " name=" + name);
        }
        else if (type.equals("PROCEDURE")) {
            if (start) {
                logger.debug("PROCEDURE line=" + line + " thread=" + thread + " name=" + name);
            }
            else {
                logger.debug("PROCEDURE_END line=" + line + " thread=" + thread + " name=" + name);
            }
        }
        else if (type.equals("FOREACH_IT")) {
            logger.debug("FOREACH_IT_" + (start ? "START" : "END") + " line=" + line + " thread=" + thread);
            if (start) {
                logger.debug("SCOPE thread=" + thread);
            }
        }
        else if (type.equals("INTERNALPROC")) {
            logger.debug("INTERNALPROC_" + (start ? "START" : "END") + "thread=" + thread + " name=" + name);
        }
        else if (type.equals("CONDITION_BLOCK")) {
            if (start) {
                logger.debug("SCOPE thread=" + thread);
            }
        }
    }
}

@@ -392,16 +392,46 @@
 n.lib;%0A%0A
+import java.util.Collections;%0A
 import j
@@ -2253,24 +2253,110 @@
      %7D%0A    %7D
+%0A    %0A    private static final List%3CDSHandle%3E EMPTY_OUTPUTS = Collections.emptyList();
 %0A%0A    privat
@@ -2420,32 +2420,70 @@
 boolean deep) %7B%0A
+    %09if (outputs.length() != 0) %7B%0A    
         String%5B%5D
@@ -2507,24 +2507,28 @@
 split(%22,%22);%0A
+    
         List
@@ -2566,24 +2566,28 @@
 SHandle%3E();%0A
+    
         for 
@@ -2614,24 +2614,28 @@
 ) %7B%0A        
+    
 %09if (deep) %7B
@@ -2643,16 +2643,20 @@
         
+  
+  
 %09    try
@@ -2658,16 +2658,20 @@
   try %7B%0A
+    
         
@@ -2742,34 +2742,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -2810,24 +2810,28 @@
 eption e) %7B%0A
+    
             
@@ -2905,26 +2905,32 @@
         
-%7D%0A
+    %7D%0A  
         
 %09%7D%0A     
@@ -2913,35 +2913,41 @@
     %7D%0A          
+  
 %09%7D%0A
+    
         %09else %7B%0A
@@ -2954,16 +2954,20 @@
         
+    
 %09%09l.add(
@@ -3012,35 +3012,43 @@
 name));%0A        
-%09%7D%0A
+    %09%7D%0A    
         %7D%0A      
@@ -3049,16 +3049,20 @@
         
+    
 WaitingT
@@ -3092,24 +3092,31 @@
 (stack, l);%0A
+    %09%7D%0A
     %7D%0A%0A    p

don't record outputs for things that don't have an output