/*******************************************************************************
 * Copyright (c) 2000, 2015 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.jdi.internal;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
import org.eclipse.jdi.internal.jdwp.JdwpFrameID;
import org.eclipse.jdi.internal.jdwp.JdwpID;
import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;

import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.InvalidStackFrameException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.Locatable;
import com.sun.jdi.Location;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.StackFrame;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VMMismatchException;
import com.sun.jdi.Value;

/**
 * this class implements the corresponding interfaces declared by the JDI
 * specification. See the com.sun.jdi package for more information.
 *
 */
public class StackFrameImpl extends MirrorImpl implements StackFrame, Locatable {
	/** FrameID that corresponds to this reference. */
	private JdwpFrameID fFrameID;
	/** Thread under which this frame's method is running. */
	private ThreadReferenceImpl fThread;
	/** Location of the current instruction in the frame. */
	private LocationImpl fLocation;

	/**
	 * Creates new StackFrameImpl.
	 */
	public StackFrameImpl(VirtualMachineImpl vmImpl, JdwpFrameID ID,
			ThreadReferenceImpl thread, LocationImpl location) {
		super("StackFrame", vmImpl); //$NON-NLS-1$
		fFrameID = ID;
		fThread = thread;
		fLocation = location;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.StackFrame#getValue(com.sun.jdi.LocalVariable)
	 */
	@Override
	public Value getValue(LocalVariable variable)
			throws IllegalArgumentException, InvalidStackFrameException,
			VMMismatchException {
		ArrayList<LocalVariable> list = new ArrayList<>(1);
		list.add(variable);
		return getValues(list).get(variable);
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.StackFrame#getValues(java.util.List)
	 */
	@Override
	public Map<LocalVariable, Value> getValues(List<? extends LocalVariable> variables) throws IllegalArgumentException,
			InvalidStackFrameException, VMMismatchException {
		// Note that this information should not be cached.
		Map<LocalVariable, Value> map = new HashMap<>(variables.size());
		// if the variable list is empty, nothing to do
		if (variables.isEmpty()) {
			return map;
		}
		/*
		 * If 'this' is requested, we have to use a special JDWP request.
		 * Therefore, we remember the positions in the list of requests for
		 * 'this'.
		 */
		int sizeAll = variables.size();
		int sizeThis = 0;
		boolean[] isThisValue = new boolean[sizeAll];
		for (int i = 0; i < sizeAll; i++) {
			LocalVariableImpl var = (LocalVariableImpl) variables.get(i);
			isThisValue[i] = var.isThis();
			if (isThisValue[i]) {
				sizeThis++;
			}
		}
		int sizeNotThis = sizeAll - sizeThis;

		if (sizeThis > 0) {
			Value thisValue = thisObject();
			for (int i = 0; i < sizeAll; i++) {
				if (isThisValue[i]) {
					map.put(variables.get(i), thisValue);
				}
			}
		}

		// If only 'this' was requested, we're finished.
		if (sizeNotThis == 0) {
			return map;
		}

		// Request values for local variables other than 'this'.
		initJdwpRequest();
		try {
			ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
			DataOutputStream outData = new DataOutputStream(outBytes);
			writeWithThread(this, outData);
			writeInt(sizeNotThis, "size", outData); //$NON-NLS-1$
			for (int i = 0; i < sizeAll; i++) {
				if (!isThisValue[i]) {
					LocalVariableImpl var = (LocalVariableImpl) variables
							.get(i);
					checkVM(var);
					writeInt(var.slot(), "slot", outData); //$NON-NLS-1$
					writeByte(var.tag(), "tag", JdwpID.tagMap(), outData); //$NON-NLS-1$
				}
			}
			JdwpReplyPacket replyPacket = requestVM(
					JdwpCommandPacket.SF_GET_VALUES, outBytes);
			defaultReplyErrorHandler(replyPacket.errorCode());

			DataInputStream replyData = replyPacket.dataInStream();
			int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
			if (nrOfElements != sizeNotThis)
				throw new InternalError(
						JDIMessages.StackFrameImpl_Retrieved_a_different_number_of_values_from_the_VM_than_requested_1);

			for (int i = 0, j = 0; i < sizeAll; i++) {
				if (!isThisValue[i])
					map.put(variables.get(j++),
							ValueImpl.readWithTag(this, replyData));
			}
			return map;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
			return null;
		} finally {
			handledJdwpRequest();
		}
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.StackFrame#getArgumentValues()
	 */
	@Override
	public List<Value> getArgumentValues() throws InvalidStackFrameException {
		if (!thread().isSuspended()) {
			throw new InvalidStackFrameException(
					JDIMessages.StackFrameImpl_no_argument_values_available);
		}
		try {
			List<LocalVariable> list = location().method().variables();
			ArrayList<Value> ret = new ArrayList<>();
			LocalVariable var = null;
			for (Iterator<LocalVariable> iter = list.iterator(); iter.hasNext();) {
				var = iter.next();
				if (var.isArgument()) {
					ret.add(getValue(var));
				}
			}
			return ret;
		} catch (AbsentInformationException e) {
			JDIDebugPlugin.log(e);
			return null;
		}
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.StackFrame#location()
	 */
	@Override
	public Location location() {
		return fLocation;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.StackFrame#setValue(com.sun.jdi.LocalVariable, com.sun.jdi.Value)
	 */
	@Override
	public void setValue(LocalVariable var, Value value)
			throws InvalidTypeException, ClassNotLoadedException {
		// Note that this information should not be cached.
		initJdwpRequest();
		try {
			ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
			DataOutputStream outData = new DataOutputStream(outBytes);
			((ThreadReferenceImpl) thread()).write(this, outData);
			write(this, outData);
			writeInt(1, "size", outData); // We only set one field //$NON-NLS-1$
			checkVM(var);
			writeInt(((LocalVariableImpl) var).slot(), "slot", outData); //$NON-NLS-1$

			// check the type and the VM of the value, convert the value if
			// needed.
			ValueImpl checkedValue = ValueImpl.checkValue(value, var.type(),
					virtualMachineImpl());

			if (checkedValue != null) {
				checkedValue.writeWithTag(this, outData);
			} else {
				ValueImpl.writeNullWithTag(this, outData);
			}

			JdwpReplyPacket replyPacket = requestVM(
					JdwpCommandPacket.SF_SET_VALUES, outBytes);
			switch (replyPacket.errorCode()) {
			case JdwpReplyPacket.INVALID_CLASS:
				throw new ClassNotLoadedException(var.typeName());
			}
			defaultReplyErrorHandler(replyPacket.errorCode());
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
		} finally {
			handledJdwpRequest();
		}
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.StackFrame#thisObject()
	 */
	@Override
	public ObjectReference thisObject() throws InvalidStackFrameException {
		// Note that this information should not be cached.
		initJdwpRequest();
		try {
			ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
			DataOutputStream outData = new DataOutputStream(outBytes);
			writeWithThread(this, outData);

			JdwpReplyPacket replyPacket = requestVM(
					JdwpCommandPacket.SF_THIS_OBJECT, outBytes);
			defaultReplyErrorHandler(replyPacket.errorCode());

			DataInputStream replyData = replyPacket.dataInStream();
			ObjectReference result = ObjectReferenceImpl.readObjectRefWithTag(
					this, replyData);
			return result;
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
			return null;
		} finally {
			handledJdwpRequest();
		}
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.StackFrame#thread()
	 */
	@Override
	public ThreadReference thread() {
		return fThread;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.StackFrame#visibleVariableByName(java.lang.String)
	 */
	@Override
	public LocalVariable visibleVariableByName(String name)
			throws AbsentInformationException {
		Iterator<LocalVariable> iter = visibleVariables().iterator();
		while (iter.hasNext()) {
			LocalVariableImpl var = (LocalVariableImpl) iter.next();
			if (var.name().equals(name)) {
				return var;
			}
		}

		return null;
	}

	/* (non-Javadoc)
	 * @see com.sun.jdi.StackFrame#visibleVariables()
	 */
	@Override
	public List<LocalVariable> visibleVariables() throws AbsentInformationException {
		List<LocalVariable> variables = fLocation.method().variables();
		Iterator<LocalVariable> iter = variables.iterator();
		List<LocalVariable> visibleVars = new ArrayList<>(variables.size());
		while (iter.hasNext()) {
			LocalVariableImpl var = (LocalVariableImpl) iter.next();
			// Only return local variables other than the this pointer.
			if (var.isVisible(this) && !var.isThis()) {
				visibleVars.add(var);
			}
		}
		return visibleVars;
	}

	/**
	 * @return Returns the hash code value.
	 */
	@Override
	public int hashCode() {
		return fThread.hashCode() + fFrameID.hashCode();
	}

	/**
	 * @return Returns true if two mirrors refer to the same entity in the
	 *         target VM.
	 * @see java.lang.Object#equals(Object)
	 */
	@Override
	public boolean equals(Object object) {
		return object != null && object.getClass().equals(this.getClass())
				&& fThread.equals(((StackFrameImpl) object).fThread)
				&& fFrameID.equals(((StackFrameImpl) object).fFrameID);
	}

	/**
	 * Writes JDWP representation.
	 */
	public void write(MirrorImpl target, DataOutputStream out)
			throws IOException {
		fFrameID.write(out);
		if (target.fVerboseWriter != null) {
			target.fVerboseWriter.println("stackFrame", fFrameID.value()); //$NON-NLS-1$
		}
	}

	/**
	 * Writes JDWP representation.
	 */
	public void writeWithThread(MirrorImpl target, DataOutputStream out)
			throws IOException {
		fThread.write(target, out);
		write(target, out);
	}

	/**
	 * @return Reads JDWP representation and returns new instance.
	 */
	public static StackFrameImpl readWithLocation(MirrorImpl target,
			ThreadReferenceImpl thread, DataInputStream in) throws IOException {
		VirtualMachineImpl vmImpl = target.virtualMachineImpl();
		JdwpFrameID ID = new JdwpFrameID(vmImpl);
		ID.read(in);
		if (target.fVerboseWriter != null) {
			target.fVerboseWriter.println("stackFrame", ID.value()); //$NON-NLS-1$
		}

		if (ID.isNull()) {
			return null;
		}
		LocationImpl location = LocationImpl.read(target, in);
		if (location == null) {
			return null;
		}

		return new StackFrameImpl(vmImpl, ID, thread, location);
	}
}
