/*******************************************************************************
 * Copyright (c) 2005, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Bjorn Freeman-Benson - initial API and implementation
 *     Pawel Piech (Wind River) - ported PDA Virtual Machine to Java (Bug 261400)
 *******************************************************************************/
package org.eclipse.debug.examples.core.pda.model;

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

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.examples.core.pda.protocol.PDADataCommand;
import org.eclipse.debug.examples.core.pda.protocol.PDADropFrameCommand;
import org.eclipse.debug.examples.core.pda.protocol.PDAEvent;
import org.eclipse.debug.examples.core.pda.protocol.PDAListResult;
import org.eclipse.debug.examples.core.pda.protocol.PDANoSuchLabelEvent;
import org.eclipse.debug.examples.core.pda.protocol.PDAPopDataCommand;
import org.eclipse.debug.examples.core.pda.protocol.PDAPushDataCommand;
import org.eclipse.debug.examples.core.pda.protocol.PDAResumeCommand;
import org.eclipse.debug.examples.core.pda.protocol.PDAResumedEvent;
import org.eclipse.debug.examples.core.pda.protocol.PDARunControlEvent;
import org.eclipse.debug.examples.core.pda.protocol.PDAStackCommand;
import org.eclipse.debug.examples.core.pda.protocol.PDAStackCommandResult;
import org.eclipse.debug.examples.core.pda.protocol.PDAStepCommand;
import org.eclipse.debug.examples.core.pda.protocol.PDASuspendCommand;
import org.eclipse.debug.examples.core.pda.protocol.PDASuspendedEvent;
import org.eclipse.debug.examples.core.pda.protocol.PDAUnimplementedInstructionEvent;
import org.eclipse.debug.examples.core.pda.protocol.PDAVMResumedEvent;
import org.eclipse.debug.examples.core.pda.protocol.PDAVMSuspendedEvent;

/**
 * A PDA thread. A PDA VM is single threaded.
 */
public class PDAThread extends PDADebugElement implements IThread, IPDAEventListener {
	
    /**
     * ID of this thread as reported by PDA.
     */
    private final int fThreadId;
    
	/**
	 * Breakpoint this thread is suspended at or <code>null</code>
	 * if none.
	 */
	private IBreakpoint fBreakpoint;
	
	/**
	 * Whether this thread is stepping
	 */
	private boolean fStepping = false;
	
	/**
	 * Whether this thread is suspended
	 */
	private boolean fSuspended = false;

	/**
	 * Most recent error event or <code>null</code>
	 */
	private String fErrorEvent;
	
	/**
	 * Table mapping stack frames to current variables
	 */
	private Map fVariables = Collections.synchronizedMap(new HashMap());
	
	/**
	 * Constructs a new thread for the given target
	 * 
	 * @param target VM
	 */
	public PDAThread(PDADebugTarget target, int threadId) {
		super(target);
		fThreadId = threadId;
	}
	
	/**
	 * Called by the debug target after the thread is created.
	 * 
	 * @since 3.5
	 */
	void start() {
	    fireCreationEvent();
        getPDADebugTarget().addEventListener(this);
	}
	
    /**
     * Called by the debug target before the thread is removed.
     * 
     * @since 3.5
     */
	void exit() {
        getPDADebugTarget().removeEventListener(this);
        fireTerminateEvent();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getStackFrames()
	 */
	public IStackFrame[] getStackFrames() throws DebugException {
		if (isSuspended()) {
		    PDAStackCommandResult result = (PDAStackCommandResult)sendCommand(new PDAStackCommand(fThreadId));
            IStackFrame[] frames = new IStackFrame[result.fFrames.length];
		    for (int i = 0; i < result.fFrames.length; i++) {
		        frames[frames.length - i - 1] = new PDAStackFrame(this, result.fFrames[i], i);
			}
            return frames;
		}
		return new IStackFrame[0];
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#hasStackFrames()
	 */
	public boolean hasStackFrames() throws DebugException {
		return isSuspended();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getPriority()
	 */
	public int getPriority() throws DebugException {
		return 0;
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getTopStackFrame()
	 */
	public IStackFrame getTopStackFrame() throws DebugException {
		IStackFrame[] frames = getStackFrames();
		if (frames.length > 0) {
			return frames[0];
		}
		return null;
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getName()
	 */
	public String getName() {
		return "Main thread";
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getBreakpoints()
	 */
	public synchronized IBreakpoint[] getBreakpoints() {
		if (fBreakpoint == null) {
			return new IBreakpoint[0];
		}
		return new IBreakpoint[]{fBreakpoint};
	}
	
	/**
	 * Notifies this thread it has been suspended by the given breakpoint.
	 * 
	 * @param breakpoint breakpoint
	 */
	public synchronized void suspendedBy(IBreakpoint breakpoint) {
		fBreakpoint = breakpoint;
		suspended(DebugEvent.BREAKPOINT);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
	 */
	public boolean canResume() {
		return isSuspended() && !getDebugTarget().isSuspended();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
	 */
	public boolean canSuspend() {
		return !isSuspended();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
	 */
	public boolean isSuspended() {
	    if (getDebugTarget().isTerminated()) {
	        return false;
	    }
	    if (getDebugTarget().isSuspended()) {
	        return true;
	    }
	    synchronized (this) {
	        return fSuspended;
	    }
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#resume()
	 */
	public void resume() throws DebugException {
		//#ifdef ex2
//#		// TODO: Exercise 2 - send resume request to interpreter		
		//#else
		sendCommand(new PDAResumeCommand(fThreadId));
		//#endif
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
	 */
	public void suspend() throws DebugException {
		//#ifdef ex2
//#		// TODO: Exercise 2 - send suspend request to interpreter		
		//#else
	    sendCommand(new PDASuspendCommand(fThreadId));
		//#endif
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#canStepInto()
	 */
	public boolean canStepInto() {
		return false;
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#canStepOver()
	 */
	public boolean canStepOver() {
		return isSuspended();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#canStepReturn()
	 */
	public boolean canStepReturn() {
		return false;
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#isStepping()
	 */
	public boolean isStepping() {
		return fStepping;
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#stepInto()
	 */
	public void stepInto() throws DebugException {
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#stepOver()
	 */
	public void stepOver() throws DebugException {
		sendCommand(new PDAStepCommand(fThreadId));
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#stepReturn()
	 */
	public void stepReturn() throws DebugException {
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
	 */
	public boolean canTerminate() {
		return !isTerminated();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
	 */
	public boolean isTerminated() {
		return getDebugTarget().isTerminated();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ITerminate#terminate()
	 */
	public void terminate() throws DebugException {
	    getDebugTarget().terminate();
	}
	
	/**
	 * Sets whether this thread is stepping
	 * 
	 * @param stepping whether stepping
	 */
	private synchronized void setStepping(boolean stepping) {
		fStepping = stepping;
	}
	
	/**
	 * Sets whether this thread is suspended
	 * 
	 * @param suspended whether suspended
	 */
	private synchronized  void setSuspended(boolean suspended) {
		fSuspended = suspended;
	}

	/**
	 * Sets the most recent error event encountered, or <code>null</code>
	 * to clear the most recent error
	 * 
	 * @param event one of 'unimpinstr' or 'nosuchlabel' or <code>null</code>
	 */
	private synchronized void setError(String event) {
		fErrorEvent = event;
	}

	/**
	 * Returns the most recent error event encountered since the last
	 * suspend, or <code>null</code> if none.
	 * 
	 * @return the most recent error event encountered since the last
	 * suspend, or <code>null</code> if none
	 */
	public Object getError() {
		return fErrorEvent;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
	 */
	public void handleEvent(PDAEvent _event) {
	    if (_event instanceof PDARunControlEvent && fThreadId == ((PDARunControlEvent)_event).fThreadId) {
	        PDARunControlEvent event = (PDARunControlEvent)_event;
    		// clear previous state
    		fBreakpoint = null;
    		setStepping(false);
    		
    		// handle events
    		if (event instanceof PDAResumedEvent || event instanceof PDAVMResumedEvent) {
    			setSuspended(false);
    			if ("step".equals(event.fReason)) {
    				setStepping(true);
    				resumed(DebugEvent.STEP_OVER);
    			//#ifdef ex2
    //#			}
    //#			// TODO: Exercise 2 - handle/fire "client" resume event
    			//#else	
    			} else if ("client".equals(event.fReason)) {
    				resumed(DebugEvent.CLIENT_REQUEST);
    			}
    			//#endif
    			//#ifdef ex5
    //#			// TODO: Exercise 5 - handle start of drop event
    			//#else
    			else if ("drop".equals(event.fReason)) {
    				resumed(DebugEvent.STEP_RETURN);
    			}
    			//#endif
    		} else if (event instanceof PDASuspendedEvent || event instanceof PDAVMSuspendedEvent) {
    			setSuspended(true);
    			//#ifdef ex2
    //#			// TODO: Exercise 2 - handle/fire "client" suspend event
    //#			if (event.endsWith("step")) {
    //#				suspended(DebugEvent.STEP_END);
    //#			} else if (event.startsWith("suspended event") && getError() != null) {
    //#				exceptionHit();
    //#			}
    			//#else
    			if ("client".equals(event.fReason)) {
    				suspended(DebugEvent.CLIENT_REQUEST);
    			} else if ("step".equals(event.fReason)) {
    				suspended(DebugEvent.STEP_END);
    			} else if ("event".equals(event.fReason) && getError() != null) {
    				exceptionHit();
    			} 
    			//#endif
    			//#ifdef ex5
    //#			// TODO: Exercise 5 - handle end of drop event
    			//#else
    			else if ("drop".equals(event.fReason)) {
    				suspended(DebugEvent.STEP_END);
    			}
    			//#endif
    		} else if (_event instanceof PDANoSuchLabelEvent ||
    		           _event instanceof PDAUnimplementedInstructionEvent) 
    		{
    			setError(event.fMessage);
    		}
	    }    		
	}
	
	/**
	 * Notification the target has resumed for the given reason.
	 * Clears any error condition that was last encountered and
	 * fires a resume event, and clears all cached variables
	 * for stack frames.
	 * 
	 * @param detail reason for the resume
	 */
	private void resumed(int detail) {
		setError(null);
		fVariables.clear();
		fireResumeEvent(detail);
	}
	
	/**
	 * Notification the target has suspended for the given reason
	 * 
	 * @param detail reason for the suspend
	 */
	private void suspended(int detail) {
		fireSuspendEvent(detail);
	}

	/**
     * Notification an error was encountered. Fires a breakpoint
     * suspend event.
     */
    private void exceptionHit() {
    	suspended(DebugEvent.BREAKPOINT);
    }  
	
	/**
	 * Sets the current variables for the given stack frame. Called
	 * by PDA stack frame when it is created.
	 * 
	 * @param frame
	 * @param variables
	 */
	protected void setVariables(IStackFrame frame, IVariable[] variables) {
		synchronized (fVariables) {
			fVariables.put(frame, variables);
		}
	}
	
	/**
	 * Returns the current variables for the given stack frame, or
	 * <code>null</code> if none.
	 * 
	 * @param frame stack frame
	 * @return variables or <code>null</code>
	 */
	protected IVariable[] getVariables(IStackFrame frame) {
		synchronized (fVariables) {
			IVariable[] variables = (IVariable[]) fVariables.get(frame);
			if (variables == null) {
				return new IVariable[0];
			}
			return variables;
		}
	}
	
	/**
	 * Pops the top frame off the callstack.
	 *
	 * @throws DebugException
     * 
     * @since 3.5
	 */
	public void popFrame() throws DebugException {
		//#ifdef ex5
//#		// TODO: Exercise 5 - send drop request		
		//#else
		sendCommand(new PDADropFrameCommand(fThreadId));
		//#endif
	}
	
	/**
	 * Returns whether this thread can pop the top stack frame.
	 *
	 * @return whether this thread can pop the top stack frame
	 * 
	 * @since 3.5
	 */
	public boolean canPopFrame() {
		//#ifdef ex5
//#		// TODO: Exercise 5 - allow pop if there is more than 1 frame on the stack		
		//#else
		try {
			return getStackFrames().length > 1;
		} catch (DebugException e) {
		}
		//#endif
		return false;
	}
	
    /**
     * Returns the values on the data stack (top down)
     * 
     * @return the values on the data stack (top down)
     * 
     * @since 3.5
     */
    public IValue[] getDataStack() throws DebugException {
        PDAListResult result = (PDAListResult)sendCommand(new PDADataCommand(fThreadId));
        if (result.fValues.length > 0) {
            IValue[] values = new IValue[result.fValues.length];
            for (int i = 0; i < result.fValues.length; i++) {
                values[values.length - i - 1] = new PDAStackValue(this, result.fValues[i], i);
            }
            return values;
        }
        return new IValue[0];       
    }
    	   
    /**
     * Returns whether popping the data stack is currently permitted
     *  
     * @return whether popping the data stack is currently permitted
     * 
     * @since 3.5
     */
    public boolean canPopData() {
        try {
            return !isTerminated() && isSuspended() && getDataStack().length > 0;
        } catch (DebugException e) {
        }
        return false;
    }
    
    /**
     * Pops and returns the top of the data stack
     * 
     * @return the top value on the stack 
     * @throws DebugException if the stack is empty or the request fails
     * 
     * @since 3.5
     */
    public IValue popData() throws DebugException {
        IValue[] dataStack = getDataStack();
        if (dataStack.length > 0) {
            sendCommand(new PDAPopDataCommand(fThreadId));
            return dataStack[0];
        }
        requestFailed("Empty stack", null);
        return null;
    }
    
    /**
     * Returns whether pushing a value is currently supported.
     * 
     * @return whether pushing a value is currently supported
     * 
     * @since 3.5
     */
    public boolean canPushData() {
        return !isTerminated() && isSuspended();
    }
    
    /**
     * Pushes a value onto the stack.
     * 
     * @param value value to push
     * @throws DebugException on failure
     * 
     * @since 3.5
     */
    public void pushData(String value) throws DebugException {
        sendCommand(new PDAPushDataCommand(fThreadId, value));
    }

    /**
     * Returns this thread's unique identifier
     * 
     * @return this thread's unique identifier
     * 
     * @since 3.5
     */
	public int getIdentifier() {
	    return fThreadId;
	}
}
