/*******************************************************************************
 * Copyright (c) 2010 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
 *******************************************************************************/
package org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.jsdt.debug.core.jsdi.StackFrame;
import org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference;
import org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.StepRequest;
import org.eclipse.wst.jsdt.debug.internal.crossfire.Tracing;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.Attributes;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.CFRequestPacket;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.CFResponsePacket;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.Commands;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.JSON;

/**
 * Default implementation of {@link ThreadReference} for Crossfire
 * 
 * @since 1.0
 */
public class CFThreadReference extends CFMirror implements ThreadReference {
	
	static final int RUNNING = 0;
	static final int SUSPENDED = 1;
	static final int TERMINATED = 2;
	
	private String id = null;
	private String href = null;
	private int state = RUNNING;
	private ArrayList frames = null;
	private int stepkind = -1;
	
	/**
	 * Constructor
	 * 
	 * @param vm
	 * @param id
	 * @param href
	 */
	public CFThreadReference(VirtualMachine vm, String id, String href) {
		super(vm);
		this.id = id;
		this.href = href;
	}
	
	/**
	 * Constructor
	 * @param vm
	 * @param json
	 */
	public CFThreadReference(VirtualMachine vm, Map json) {
		super(vm);
		this.id = (String) json.get(Attributes.CROSSFIRE_ID);
		if(this.id == null) {
			this.id = (String) json.get(Attributes.CONTEXT_ID);
		}
		this.href = (String) json.get(Attributes.HREF);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#frameCount()
	 */
	public int frameCount() {
		return frames == null ? 0 : frames.size();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#frame(int)
	 */
	public synchronized StackFrame frame(int index) {
		if(frames == null || index < 0 || index > frames.size()) {
			return null;
		}
		return (StackFrame) frames.get(index);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#frames()
	 */
	public synchronized List frames() {
		//TODO we require some way to batch retrieve the frames from a given context
		//unless there is only ever one frame?
		if(frames == null) {
			CFRequestPacket request = new CFRequestPacket(Commands.BACKTRACE, id);
			request.setArgument(Attributes.FROM_FRAME, new Integer(0));
			request.setArgument(Attributes.INCLUDE_SCOPES, Boolean.TRUE);
			CFResponsePacket response = crossfire().sendRequest(request);
			if(response.isSuccess()) {
				frames = new ArrayList();
				ArrayList frms = (ArrayList) response.getBody().get(Attributes.FRAMES);
				if(frms != null) {
					Map fmap = null;
					for (int i = 0; i < frms.size(); i++) {
						fmap = (Map) frms.get(i);
						//XXX hack to prevent http://code.google.com/p/fbug/issues/detail?id=4203
						if(fmap.containsKey(Attributes.SCRIPT)) {
							frames.add(new CFStackFrame(virtualMachine(), this, fmap));
						}
						else if(TRACE) {
							Tracing.writeString("STACKFRAME [got bogus stackframe infos]: "+fmap.values().toString()); //$NON-NLS-1$
						}
					}
				}
			}
			else {
				if(TRACE) {
					Tracing.writeString("STACKFRAME [backtrace request failed]: "+JSON.serialize(request)); //$NON-NLS-1$
				}
				return Collections.EMPTY_LIST;
			}
		}
		return frames;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#interrupt()
	 */
	public void interrupt() {
		try {
			resume();
		}
		finally {
			state = TERMINATED;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#resume()
	 */
	public void resume() {
		if(isSuspended()) {
			CFRequestPacket request = new CFRequestPacket(Commands.CONTINUE, id);
			String step = resolveStepKind();
			if(step != null) {
				request.setArgument(Attributes.STEPACTION, step);
			}
			try {
				CFResponsePacket response = crossfire().sendRequest(request);
				if(response.isSuccess()) {
					state = RUNNING;
				}
				else if(TRACE) {
					Tracing.writeString("THREAD [failed continue request] "+JSON.serialize(request)); //$NON-NLS-1$
				}
			}
			finally {
				clearFrames();
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#suspend()
	 */
	public void suspend() {
		if(isRunning()) {
			CFRequestPacket request = new CFRequestPacket(Commands.SUSPEND, id);
			try {
				CFResponsePacket response = crossfire().sendRequest(request);
				if(response.isSuccess()) {
					//XXX catch in case the last resume failed
					state = SUSPENDED;
				}
				else if(TRACE) {
					Tracing.writeString("THREAD [failed suspend request]: "+JSON.serialize(request)); //$NON-NLS-1$
				}
			}
			finally {
				clearFrames();
			}
		}
	}

	/**
	 * Clears out any stale stack frames
	 */
	void clearFrames() {
		if(frames != null) {
			frames.clear();
			frames = null;
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#status()
	 */
	public int status() {
		return THREAD_STATUS_RUNNING;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#isAtBreakpoint()
	 */
	public boolean isAtBreakpoint() {
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#isSuspended()
	 */
	public boolean isSuspended() {
		return state == SUSPENDED;
	}

	/**
	 * @return if the thread is in a running state
	 */
	public boolean isRunning() {
		return state == RUNNING;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference#name()
	 */
	public String name() {
		return NLS.bind(Messages.thread_name, new Object[] {id, href});
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("ThreadReference: [crossfire_id - ").append(id).append("] [href - ").append(href).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		return buffer.toString();
	}
	
	/**
	 * Returns the Crossfire id for this thread
	 * 
	 * @return the id
	 */
	public String id() {
		return id;
	}
	
	/**
	 * Returns the href context for this thread
	 * 
	 * return the href context
	 */
	public String href() {
		return href;
	}
	
	/**
	 * Marks the thread as suspended or not. This is a call-back from the 
	 * VM when suspending a VM.
	 * 
	 * @param suspended
	 */
	public void markSuspended(boolean suspended) {
		//XXX catch - this causes a state change
		clearFrames();
		state = suspended ? SUSPENDED : RUNNING;
	}
	
	/**
	 * Sets the current step kind kind to perform, or -1 to remove the kind
	 * @param stepkind
	 */
	public void setStep(int step) {
		this.stepkind = step;
	}
	
	/**
	 * @return the step kind to use in the continue request or <code>null</code>
	 */
	String resolveStepKind() {
		if(stepkind != -1) {
			switch(stepkind) {
				case StepRequest.STEP_INTO: return Commands.STEP_IN;
				case StepRequest.STEP_OUT: return Commands.STEP_OUT;
				case StepRequest.STEP_OVER: return Commands.STEP_NEXT;
			}
		}
		return null;
	}
}
