/*******************************************************************************
 * 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.io.PrintWriter;
import java.util.Date;
import java.util.Map;

import org.eclipse.jdi.Bootstrap;
import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
import org.eclipse.jdi.internal.jdwp.JdwpPacket;
import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
import org.eclipse.jdi.internal.jdwp.JdwpString;
import org.eclipse.jdt.internal.debug.core.JDIDebugOptions;

import com.sun.jdi.ClassNotPreparedException;
import com.sun.jdi.InternalException;
import com.sun.jdi.InvalidStackFrameException;
import com.sun.jdi.Mirror;
import com.sun.jdi.NativeMethodException;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.VMMismatchException;
import com.sun.jdi.VMOutOfMemoryException;
import com.sun.jdi.VirtualMachine;

/**
 * this class implements the corresponding interfaces declared by the JDI
 * specification. See the com.sun.jdi package for more information.
 * 
 */
public class MirrorImpl implements Mirror {

	/** Description of Mirror object. */
	protected String fDescription;
	/** Virtual Machine of Mirror object. */
	private VirtualMachineImpl fVirtualMachineImpl;
	/**
	 * VerboseWriter where verbose info is written to, null if no verbose must
	 * be given.
	 */
	protected VerboseWriter fVerboseWriter = null;
	/**
	 * True if a Jdwp request has been sent to the VM and the response is not
	 * yet (fully) processed.
	 */
	private boolean fPendingJdwpRequest = false;

	/**
	 * Constructor only to be used by Virtual Machine objects: stores
	 * description of Mirror object and Virtual Machine.
	 */
	public MirrorImpl(String description) {
		fDescription = description;
		fVirtualMachineImpl = (VirtualMachineImpl) this;
		PrintWriter writer = ((VirtualMachineManagerImpl) org.eclipse.jdi.Bootstrap
				.virtualMachineManager()).verbosePrintWriter();
		if (writer != null)
			fVerboseWriter = new VerboseWriter(writer);
	}

	/**
	 * Constructor stores description of Mirror object and its Virtual Machine.
	 */
	public MirrorImpl(String description, VirtualMachineImpl virtualMachineImpl) {
		fVirtualMachineImpl = virtualMachineImpl;
		fDescription = description;
		PrintWriter writer = ((VirtualMachineManagerImpl) org.eclipse.jdi.Bootstrap
				.virtualMachineManager()).verbosePrintWriter();
		if (writer != null)
			fVerboseWriter = new VerboseWriter(writer);
	}

	/**
	 * @return Returns description of Mirror object.
	 */
	@Override
	public String toString() {
		return fDescription;
	}

	/**
	 * @return Returns Virtual Machine of Mirror object.
	 */
	@Override
	public VirtualMachine virtualMachine() {
		return fVirtualMachineImpl;
	}

	/**
	 * @return Returns Virtual Machine implementation of Mirror object.
	 */
	public VirtualMachineImpl virtualMachineImpl() {
		return fVirtualMachineImpl;
	}

	/**
	 * Processing before each Jdwp event.
	 */
	public void initJdwpEventSet(JdwpCommandPacket commandPacket) {
		if (fVerboseWriter != null) {
			fVerboseWriter.println("Received event set"); //$NON-NLS-1$
			fVerboseWriter.println("length", commandPacket.getLength()); //$NON-NLS-1$
			fVerboseWriter.println("id", commandPacket.getId()); //$NON-NLS-1$
			fVerboseWriter.println(
					"flags", commandPacket.getFlags(), JdwpPacket.getFlagMap()); //$NON-NLS-1$
			fVerboseWriter.println(
					"command set", (byte) (commandPacket.getCommand() >>> 8)); //$NON-NLS-1$
			fVerboseWriter
					.println("command", (byte) commandPacket.getCommand()); //$NON-NLS-1$
		}
	}

	/**
	 * Processing after each Jdwp Event.
	 */
	public void handledJdwpEventSet() {
		if (fVerboseWriter != null) {
			fVerboseWriter.println();
			fVerboseWriter.flush();
		}
	}

	/**
	 * Processing before each Jdwp request. Note that this includes building the
	 * request message and parsing the response.
	 */
	public void initJdwpRequest() {
		if (fVerboseWriter != null) {
			fVerboseWriter.gotoPosition(6);
		}
	}

	/**
	 * Writes command packet header if verbose is on.
	 */
	public void writeVerboseCommandPacketHeader(JdwpCommandPacket commandPacket) {
		if (fVerboseWriter != null) {
			int command = commandPacket.getCommand();
			int currentPosition = fVerboseWriter.position();
			fVerboseWriter.gotoPosition(0);
			fVerboseWriter.print("Sending command ("); //$NON-NLS-1$
			fVerboseWriter.printValue(command, JdwpCommandPacket.commandMap());
			fVerboseWriter.println(")"); //$NON-NLS-1$
			fVerboseWriter.println("length", commandPacket.getLength()); //$NON-NLS-1$
			fVerboseWriter.println("id", commandPacket.getId()); //$NON-NLS-1$
			fVerboseWriter.println(
					"flags", commandPacket.getFlags(), JdwpPacket.getFlagMap()); //$NON-NLS-1$
			fVerboseWriter.println("command set", (byte) (command >>> 8)); //$NON-NLS-1$
			fVerboseWriter.println("command", (byte) command); //$NON-NLS-1$
			fVerboseWriter.gotoPosition(currentPosition);
		}
	}

	/**
	 * Processing after each Jdwp Request.
	 */
	public void handledJdwpRequest() {
		if (fVerboseWriter != null && fPendingJdwpRequest) {
			fVerboseWriter.println();
			fVerboseWriter.flush();
		}
		fPendingJdwpRequest = false;
	}

	/**
	 * Performs a VM request.
	 * 
	 * @return Returns reply data.
	 */
	public JdwpReplyPacket requestVM(int command, byte[] outData) {
		JdwpCommandPacket commandPacket = new JdwpCommandPacket(command);
		commandPacket.setData(outData);
		long sent = System.currentTimeMillis();
		fVirtualMachineImpl.packetSendManager().sendPacket(commandPacket);
		fPendingJdwpRequest = true;
		writeVerboseCommandPacketHeader(commandPacket);

		JdwpReplyPacket reply = fVirtualMachineImpl.packetReceiveManager()
				.getReply(commandPacket);
		long recieved = System.currentTimeMillis();
		if (JDIDebugOptions.DEBUG_JDI_REQUEST_TIMES) {
			StringBuffer buf = new StringBuffer();
			buf.append(JDIDebugOptions.FORMAT.format(new Date(sent)));
			buf.append(" JDI Request: "); //$NON-NLS-1$
			buf.append(commandPacket.toString());
			buf.append("\n\tResponse Time: "); //$NON-NLS-1$
			buf.append(recieved - sent);
			buf.append("ms"); //$NON-NLS-1$
			buf.append(" length: "); //$NON-NLS-1$
			buf.append(reply.getLength());
			JDIDebugOptions.trace(buf.toString());
		}
		if (fVerboseWriter != null) {
			fVerboseWriter.println();
			fVerboseWriter.println("Received reply"); //$NON-NLS-1$
			fVerboseWriter.println("length", reply.getLength()); //$NON-NLS-1$
			fVerboseWriter.println("id", reply.getId()); //$NON-NLS-1$
			fVerboseWriter.println(
					"flags", reply.getFlags(), JdwpPacket.getFlagMap()); //$NON-NLS-1$
			fVerboseWriter
					.println(
							"error code", reply.errorCode(), JdwpReplyPacket.errorMap()); //$NON-NLS-1$
		}

		return reply;
	}

	/**
	 * Performs a VM request.
	 * 
	 * @return Returns reply data.
	 */
	public JdwpReplyPacket requestVM(int command, ByteArrayOutputStream outData) {
		return requestVM(command, outData.toByteArray());
	}

	/**
	 * Performs a VM request for a specified object.
	 * 
	 * @return Returns reply data.
	 */
	public JdwpReplyPacket requestVM(int command, ObjectReferenceImpl object) {
		ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
		DataOutputStream dataOutStream = new DataOutputStream(byteOutStream);
		try {
			object.write(this, dataOutStream);
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
		}
		return requestVM(command, byteOutStream);
	}

	/**
	 * Performs a VM request for a specified object.
	 * 
	 * @return Returns reply data.
	 */
	public JdwpReplyPacket requestVM(int command, ReferenceTypeImpl refType) {
		ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
		DataOutputStream dataOutStream = new DataOutputStream(byteOutStream);
		try {
			refType.write(this, dataOutStream);
		} catch (IOException e) {
			defaultIOExceptionHandler(e);
		}
		return requestVM(command, byteOutStream);
	}

	/**
	 * Performs a VM request.
	 * 
	 * @return Returns reply data.
	 */
	public JdwpReplyPacket requestVM(int command) {
		return requestVM(command, (byte[]) null);
	}

	/**
	 * Performs default error handling.
	 */
	public void defaultReplyErrorHandler(int error) {
		switch (error) {
		case JdwpReplyPacket.NONE:
			break;
		case JdwpReplyPacket.INVALID_OBJECT:
			throw new ObjectCollectedException();
		case JdwpReplyPacket.INVALID_CLASS:
			throw new ClassNotPreparedException();
		case JdwpReplyPacket.CLASS_NOT_PREPARED:
			throw new ClassNotPreparedException();
		case JdwpReplyPacket.OUT_OF_MEMORY:
			throw new VMOutOfMemoryException();
		case JdwpReplyPacket.ILLEGAL_ARGUMENT:
			throw new IllegalArgumentException();
		case JdwpReplyPacket.NATIVE_METHOD:
			throw new NativeMethodException();
		case JdwpReplyPacket.INVALID_FRAMEID:
			throw new InvalidStackFrameException();
		case JdwpReplyPacket.NOT_IMPLEMENTED:
			throw new UnsupportedOperationException();
		case JdwpReplyPacket.HCR_OPERATION_REFUSED:
			throw new org.eclipse.jdi.hcr.OperationRefusedException();
		case JdwpReplyPacket.VM_DEAD:
			throw new VMDisconnectedException();
		default:
			throw new InternalException(
					JDIMessages.MirrorImpl_Got_error_code_in_reply___1 + error,
					error);
		}
	}

	/**
	 * Performs default handling of IOException in creating or interpreting a
	 * Jdwp packet.
	 */
	public void defaultIOExceptionHandler(Exception e) {
		throw new InternalException(JDIMessages.MirrorImpl_Got_invalid_data___2
				+ e);
	}

	/**
	 * Waits for a specified command packet from the VM.
	 * 
	 * @return Returns Command Packet from VM.
	 */
	public final JdwpCommandPacket getCommandVM(int command, long timeout)
			throws InterruptedException {
		return fVirtualMachineImpl.packetReceiveManager().getCommand(command,
				timeout);
	}

	/**
	 * @exception VMMismatchException
	 *                is thrown if the Mirror argument and this mirror do not
	 *                belong to the same VirtualMachine.
	 */
	public void checkVM(Mirror mirror) throws VMMismatchException {
		if (((MirrorImpl) mirror).virtualMachineImpl() != this
				.virtualMachineImpl())
			throw new VMMismatchException();
	}

	/**
	 * Disconnects VM.
	 */
	public void disconnectVM() {
		fVirtualMachineImpl.setDisconnected(true);
		fVirtualMachineImpl.packetSendManager().disconnectVM();
		fVirtualMachineImpl.packetReceiveManager().disconnectVM();
		((VirtualMachineManagerImpl) Bootstrap.virtualMachineManager())
				.removeConnectedVM(fVirtualMachineImpl);
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public byte readByte(String description, DataInputStream in)
			throws IOException {
		byte result = in.readByte();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public short readShort(String description, DataInputStream in)
			throws IOException {
		short result = in.readShort();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public int readInt(String description, DataInputStream in)
			throws IOException {
		int result = in.readInt();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public long readLong(String description, DataInputStream in)
			throws IOException {
		long result = in.readLong();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public byte readByte(String description, Map<Integer, String> valueToString,
			DataInputStream in) throws IOException {
		byte result = in.readByte();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result, valueToString);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public short readShort(String description, Map<Integer, String> valueToString,
			DataInputStream in) throws IOException {
		short result = in.readShort();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result, valueToString);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public int readInt(String description, Map<Integer, String> valueToString, DataInputStream in)
			throws IOException {
		int result = in.readInt();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result, valueToString);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public String readString(String description, DataInputStream in)
			throws IOException {
		String result = JdwpString.read(in);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public boolean readBoolean(String description, DataInputStream in)
			throws IOException {
		boolean result = in.readBoolean();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public char readChar(String description, DataInputStream in)
			throws IOException {
		char result = in.readChar();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public double readDouble(String description, DataInputStream in)
			throws IOException {
		double result = in.readDouble();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public float readFloat(String description, DataInputStream in)
			throws IOException {
		float result = in.readFloat();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public byte[] readByteArray(int length, String description,
			DataInputStream in) throws IOException {
		byte[] result = new byte[length];
		in.readFully(result);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result);
		}
		return result;
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeByte(byte value, String description, DataOutputStream out)
			throws IOException {
		out.writeByte(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeShort(short value, String description, DataOutputStream out)
			throws IOException {
		out.writeShort(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeInt(int value, String description, DataOutputStream out)
			throws IOException {
		out.writeInt(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeLong(long value, String description, DataOutputStream out)
			throws IOException {
		out.writeLong(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeByte(byte value, String description, Map<Integer, String> valueToString,
			DataOutputStream out) throws IOException {
		out.writeByte(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value, valueToString);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeShort(short value, String description, Map<Integer, String> valueToString,
			DataOutputStream out) throws IOException {
		out.writeShort(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value, valueToString);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeInt(int value, String description, Map<Integer, String> valueToString,
			DataOutputStream out) throws IOException {
		out.writeInt(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value, valueToString);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeString(String value, String description,
			DataOutputStream out) throws IOException {
		JdwpString.write(value, out);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeBoolean(boolean value, String description,
			DataOutputStream out) throws IOException {
		out.writeBoolean(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeChar(char value, String description, DataOutputStream out)
			throws IOException {
		out.writeChar(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeDouble(double value, String description,
			DataOutputStream out) throws IOException {
		out.writeDouble(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeFloat(float value, String description, DataOutputStream out)
			throws IOException {
		out.writeFloat(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeShort(short value, String description, String[] bitNames,
			DataOutputStream out) throws IOException {
		out.writeShort(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value, bitNames);
		}
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeInt(int value, String description, String[] bitNames,
			DataOutputStream out) throws IOException {
		out.writeInt(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value, bitNames);
		}
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public byte readByte(String description, String[] bitNames,
			DataInputStream in) throws IOException {
		byte result = in.readByte();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result, bitNames);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public short readShort(String description, String[] bitNames,
			DataInputStream in) throws IOException {
		short result = in.readShort();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result, bitNames);
		}
		return result;
	}

	/**
	 * Reads Jdwp data and, if verbose is on, outputs verbose info.
	 * 
	 * @return Returns value that has been read.
	 */
	public int readInt(String description, String[] bitNames, DataInputStream in)
			throws IOException {
		int result = in.readInt();
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, result, bitNames);
		}
		return result;
	}

	/**
	 * Writes Jdwp data and, if verbose is on, outputs verbose info.
	 */
	public void writeByte(byte value, String description, String[] bitNames,
			DataOutputStream out) throws IOException {
		out.writeByte(value);
		if (fVerboseWriter != null) {
			fVerboseWriter.println(description, value, bitNames);
		}
	}

	/**
	 * @return Returns VerboseWriter where verbose info is written to, null if
	 *         no verbose must be given.
	 */
	public VerboseWriter verboseWriter() {
		return fVerboseWriter;
	}
}
