/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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) {
			StringBuilder buf = new StringBuilder();
			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;
	}
}
