package org.objectweb.proactive.core.debug.dconnection;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.rmi.UnmarshalException;

import org.objectweb.proactive.core.node.Node;
import org.objectweb.proactive.core.node.NodeException;
import org.objectweb.proactive.core.node.NodeFactory;
import org.objectweb.proactive.core.node.StartNode;
import org.objectweb.proactive.core.process.JVMProcessImpl;


public class DebuggerConnection implements Serializable {

    private static final long serialVersionUID = 2591499219438855959L;

    private static String nodeName = "DebugNode";
    private static DebuggerInformation info;

    private static boolean created = false;

    public DebuggerConnection() {
    }

    static public int getPort() {
        String sPort;
        int iPort = -1;
        File file;
        BufferedReader reader = null;

        String name = System.getProperty("debugID");
        try {
            file = new File(System.getProperty("java.io.tmpdir") + File.separator + name);
            reader = new BufferedReader(new FileReader(file));
            sPort = reader.readLine();
            iPort = Integer.parseInt(sPort);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
            }
        }
        return iPort;
    }

    /**
     * Get the information for connect a debugger. Create the debug node if it
     * does not exist.
     *
     * @return DebuggerInformation
     */
    public static DebuggerInformation getDebugInfo() {
        if (info == null) {
            Node node = getOrCreateNode();
            info = new DebuggerInformation(node, getPort());
        } else if (info.getDebuggerNode() == null) {
            info = new DebuggerInformation(getOrCreateNode(), info.getDebuggeePort());
        }
        return info;
    }

    private static Node getOrCreateNode() {
        Node node = getNode();
        try {
            if (node == null && !created) {
                JVMProcessImpl vm = new JVMProcessImpl();
                vm.setClassname(StartNode.class.getName());
                vm.setParameters(nodeName);
                vm.startProcess();
                created = true;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e2) {
                }
                node = getNode();
            }
        } catch (IOException e) {
            e.printStackTrace();
            created = false;
            return null;
        }
        return node;
    }

    public static Node getNode() {
        for (int i = 0; i < 3; i++) {
            try {
                Thread.sleep(500);
                Node node = NodeFactory.getNode(nodeName);
                if (node != null) {
                    return node;
                }
            } catch (NodeException e) {
            } catch (InterruptedException e2) {
            }
        }
        return null;
    }

    /**
     * Kill the debug node if the number of active objects <= 0
     */
    public static void removeDebugger() {
        if (info != null) {
            try {
                Node node = info.getDebuggerNode();
                info = null;
                if (node != null) {
                    // bug fix:
                    // return 0 the 1st time, 1 the second time (if there is at least one node), etc
                    // then n tests might be needed to find if there are n nodes...
                    node.getNumberOfActiveObjects();
                    if (node.getNumberOfActiveObjects() <= 0) {
                        try {
                            created = false;
                            node.getProActiveRuntime().killRT(true);
                        } catch (EOFException e) {
                        } catch (UnmarshalException e) {
                        }
                    }
                }
            } catch (NodeException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @return true if there is a debugger connected, false otherwise
     */
    public static boolean hasDebuggerConnected() {
        return info != null;
    }

}

@@ -559,16 +559,113 @@
 ssImpl;%0A
+import org.objectweb.proactive.core.process.AbstractExternalProcess.StandardOutputMessageLogger;%0A
 %0A%0Apublic
@@ -2432,16 +2432,49 @@
 essImpl(
+new StandardOutputMessageLogger()
 );%0A     
@@ -2745,32 +2745,74 @@
 Exception e2) %7B%0A
+                    e2.printStackTrace();%0A
                 

make the debugger JVM output redirected to the output of the JVM that has started it