package org.drools.base.mvel;

import org.mvel.MVELRuntime;
import org.mvel.debug.Debugger;
import org.mvel.debug.Frame;

/**
 * Debug Handler for MVEL dialect.
 * 
 * Takes care of registering breakpoints and calling required methods
 * to trigger eclipse debugger to keep breakpoints in sync etc. 
 * 
 * @author Ahti Kitsik
 *
 */
public final class MVELDebugHandler {

    private static int onBreakReturn = Debugger.CONTINUE;
    
    public final static String DEBUG_LAUNCH_KEY="mvel.debugger";
    
    private static Boolean debugMode = null;
    
    public static final boolean verbose = true;
    
	static {
		MVELRuntime.setThreadDebugger(new MVELDebugger());
	}

	/**
	 * Notify remote debugger that runtime is ready to get latest breakpoint
	 * information
	 *
	 */
	public static void receiveBreakpoints() {
	}

	/**
	 * This is catched by the remote debugger
	 *
	 * @param frame
	 */
	private final static int onBreak(Frame frame) {
        // We always fall back to Debugger.CONTINUE after each onBreak to avoid eternal step-over flag
        //int oldReturn = onBreakReturn;
        //onBreakReturn = Debugger.CONTINUE;
        //return oldReturn;
		if (verbose) {
            System.out.println("Continuing with "+(onBreakReturn==Debugger.CONTINUE?"continue":"step-over"));
        }
        return onBreakReturn;
	}

    protected final static void registerBreakpoint(String sourceName, int lineNumber) {
        if (verbose) {
            System.out.println("Registering breakpoint for "+sourceName+":"+lineNumber);
        }
        MVELRuntime.registerBreakpoint( sourceName, lineNumber );
    }
    
    protected final static void clearAllBreakpoints() {
        if (verbose) {
            System.out.println("Clearing all breakpoints");
        }
        MVELRuntime.clearAllBreakpoints();
    }
    
    protected final static void removeBreakpoint(String sourceName, int lineNumber) {
        if (verbose) {
            System.out.println("Removing breakpoint from "+sourceName+":"+lineNumber);
        }
        MVELRuntime.removeBreakpoint( sourceName, lineNumber );
    }
    
	private static class MVELDebugger implements Debugger {

        public MVELDebugger() {
        }
        
		public int onBreak(Frame frame) {
			if (verbose) {
			    System.out.println("onBreak call for "+frame.getSourceName()+":"+frame.getLineNumber());
            }
			return MVELDebugHandler.onBreak(frame);
			// This call is supposed to be catched by the remote debugger
		}

	}

    protected final static void setOnBreakReturn(int value) {
        onBreakReturn = value;
    }
    
    /**
     * Do nothing for now. ensures that class is loaded prior debug handler
     */
    public static void prepare() {
    	//do nothing
    }

    /**
     * Returns current debug mode.<br/>
     * Holds lazy initialized internal reference to improve performance.<br/>
     * Therefore you can't change System property "mvel.debugger" after isDebugMode is called at least once.<br/>
     * <br/>
     * To update debug mode at runtime use {@link MVELDebugHandler#setDebugMode(boolean)}<br/>
     * @return <code>true</code> if debug mode is enabled.
     */
    public static boolean isDebugMode() {
        if (debugMode==null) {
            debugMode = Boolean.valueOf(System.getProperty(DEBUG_LAUNCH_KEY));
        }
        return debugMode.booleanValue();
    }

    /**
     * Sets debug mode on/off.<br/>
     * Updates local MVELDebugHandler property and System property "mvel.debugger"<br/>
     * <br/>
     * There's no need to ever call this method unless you write junit tests!<br/>
     * 
     * @param b is Debug enabled?
     */
    public static void setDebugMode(boolean b) {
        debugMode = Boolean.valueOf( b );
        System.setProperty( DEBUG_LAUNCH_KEY, debugMode.toString());
    }
        
}

@@ -156,18 +156,17 @@
 lect.%0A *
- 
 %0A
+
  * Takes
@@ -290,21 +290,19 @@
 ync etc.
- 
 %0A *
- 
 %0A * @aut
@@ -421,21 +421,17 @@
 NTINUE;%0A
-    
 %0A
+
     publ
@@ -487,21 +487,17 @@
 ugger%22;%0A
-    
 %0A
+
     priv
@@ -533,20 +533,16 @@
 = null;%0A
-    
 %0A    pub
@@ -580,18 +580,15 @@
 e = 
-true;%0A    
+false;%0A
 %0A%09st
@@ -1587,37 +1587,33 @@
 Number );%0A    %7D%0A
-    
 %0A
+
     protected fi
@@ -1790,29 +1790,25 @@
 ts();%0A    %7D%0A
-    
 %0A
+
     protecte
@@ -2071,21 +2071,17 @@
 ;%0A    %7D%0A
-    
 %0A
+
 %09private
@@ -2172,25 +2172,17 @@
       %7D%0A
-        
 %0A
+
 %09%09public
@@ -2553,21 +2553,17 @@
 ;%0A    %7D%0A
-    
 %0A
+
     /**%0A
@@ -3565,17 +3565,16 @@
 %3E%0A     *
- 
 %0A     * 
@@ -3774,19 +3774,11 @@
 ;%0A    %7D%0A
-        
 %0A%7D%0A

Set MVEL debugging verbosity to false