/*******************************************************************************
 * 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.spy;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

import com.ibm.icu.text.MessageFormat;

/**
 * This class can be used to spy all JDWP packets. It should be configured 'in
 * between' the debugger application and the VM (or J9 debug proxy). Its
 * parameters are: 1) The port number to which the debugger application
 * connects; 2) The name of the host on which the VM or proxy waits for a JDWP
 * connection; 3) The port number on which the VM or proxy waits for a JDWP
 * connection; 4) The file where the trace is written to.
 *
 * Note that if this program is used for tracing JDWP activity of Leapfrog, the
 * 'debug remote program' option must be used, and the J9 proxy must first be
 * started up by hand on the port to which Leapfrog will connect. The J9 proxy
 * that is started up by Leapfrog is not used and will return immediately.
 */
public class TcpipSpy extends Thread {

	private static final byte[] handshakeBytes = "JDWP-Handshake".getBytes(); //$NON-NLS-1$
	private boolean fVMtoDebugger;
	private DataInputStream fDataIn;
	private DataOutputStream fDataOut;

	private static VerbosePacketStream out = new VerbosePacketStream(System.out);
	private static Map<Integer, JdwpConversation> fPackets = new HashMap<>();

	private static int fFieldIDSize;
	private static int fMethodIDSize;
	private static int fObjectIDSize;
	private static int fReferenceTypeIDSize;
	private static int fFrameIDSize;
	private static boolean fHasSizes;

	public TcpipSpy(boolean VMtoDebugger, InputStream in, OutputStream out) {
		fVMtoDebugger = VMtoDebugger;
		fDataIn = new DataInputStream(new BufferedInputStream(in));
		fDataOut = new DataOutputStream(new BufferedOutputStream(out));
		fHasSizes = false;
	}

	public static void main(String[] args) {
		int inPort = 0;
		String serverHost = null;
		int outPort = 0;
		String outputFile = null;
		try {
			inPort = Integer.parseInt(args[0]);
			serverHost = args[1];
			outPort = Integer.parseInt(args[2]);
			if (args.length > 3) {
				outputFile = args[3];
			}
		} catch (Exception e) {
			out.println("usage: TcpipSpy <client port> <server host> <server port> [<output file>]"); //$NON-NLS-1$
			System.exit(-1);
		}

		if (outputFile != null) {
			File file = new File(outputFile);
			out.println(MessageFormat
					.format("Writing output to {0}", new Object[] { file.getAbsolutePath() })); //$NON-NLS-1$
			try {
				out = new VerbosePacketStream(new BufferedOutputStream(
						new FileOutputStream(file)));
			} catch (FileNotFoundException e) {
				out.println(MessageFormat
						.format("Could not open {0}.  Using stdout instead", new Object[] { file.getAbsolutePath() })); //$NON-NLS-1$
			}
		}
		out.println();
		try (ServerSocket serverSock = new ServerSocket(inPort);
			Socket inSock = serverSock.accept();
			Socket outSock = new Socket(InetAddress.getByName(serverHost),
					outPort);){
			new TcpipSpy(false, inSock.getInputStream(),
					outSock.getOutputStream()).start();
			new TcpipSpy(true, outSock.getInputStream(),
					inSock.getOutputStream()).start();
		} catch (Exception e) {
			out.println(e);
		}
	}

	@Override
	public void run() {
		try {
			// Skip handshake.
			int handshakeLength;

			handshakeLength = handshakeBytes.length;
			while (handshakeLength-- > 0) {
				int b = fDataIn.read();
				fDataOut.write(b);
			}
			fDataOut.flush();

			// Print all packages.
			while (true) {
				JdwpPacket p = JdwpPacket.read(fDataIn);
				// we need to store conversation only for command send by the
				// debugger,
				// as there is no answer from the debugger to VM commands.
				if (!(fVMtoDebugger && (p.getFlags() & JdwpPacket.FLAG_REPLY_PACKET) == 0)) {
					store(p);
				}
				out.print(p, fVMtoDebugger);
				out.flush();
				p.write(fDataOut);
				fDataOut.flush();
			}
		} catch (EOFException e) {
		} catch (SocketException e) {
		} catch (IOException e) {
			out.println(MessageFormat.format(
					"Caught exception: {0}", new Object[] { e.toString() })); //$NON-NLS-1$
			e.printStackTrace(out);
		} finally {
			try {
				fDataIn.close();
				fDataOut.close();
			} catch (IOException e) {
			}
			out.flush();
		}
	}

	public static JdwpCommandPacket getCommand(int id) {
		JdwpConversation conversation = fPackets
				.get(Integer.valueOf(id));
		if (conversation != null)
			return conversation.getCommand();
		return null;
	}

	protected static void store(JdwpPacket packet) {
		int id = packet.getId();
		JdwpConversation conversation = fPackets
				.get(Integer.valueOf(id));
		if (conversation == null) {
			conversation = new JdwpConversation(id);
			fPackets.put(Integer.valueOf(id), conversation);
		}

		if ((packet.getFlags() & JdwpPacket.FLAG_REPLY_PACKET) != 0) {
			conversation.setReply((JdwpReplyPacket) packet);
		} else {
			conversation.setCommand((JdwpCommandPacket) packet);
		}
	}

	public static int getCommand(JdwpPacket packet)
			throws UnableToParseDataException {
		JdwpCommandPacket command = null;
		if (packet instanceof JdwpCommandPacket) {
			command = (JdwpCommandPacket) packet;
		} else {
			command = getCommand(packet.getId());
			if (command == null) {
				throw new UnableToParseDataException(
						"This packet is marked as reply, but there is no command with the same id.", null); //$NON-NLS-1$
			}
		}
		return command.getCommand();
	}

	public static boolean hasSizes() {
		return fHasSizes;
	}

	public static void setHasSizes(boolean value) {
		fHasSizes = value;
	}

	public static void setFieldIDSize(int fieldIDSize) {
		fFieldIDSize = fieldIDSize;
	}

	public static int getFieldIDSize() {
		return fFieldIDSize;
	}

	public static void setMethodIDSize(int methodIDSize) {
		fMethodIDSize = methodIDSize;
	}

	public static int getMethodIDSize() {
		return fMethodIDSize;
	}

	public static void setObjectIDSize(int objectIDSize) {
		fObjectIDSize = objectIDSize;
	}

	public static int getObjectIDSize() {
		return fObjectIDSize;
	}

	public static void setReferenceTypeIDSize(int referenceTypeIDSize) {
		fReferenceTypeIDSize = referenceTypeIDSize;
	}

	public static int getReferenceTypeIDSize() {
		return fReferenceTypeIDSize;
	}

	public static void setFrameIDSize(int frameIDSize) {
		fFrameIDSize = frameIDSize;
	}

	public static int getFrameIDSize() {
		return fFrameIDSize;
	}
}
