/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdi.internal.jdwp;


import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * This class implements the corresponding Java Debug Wire Protocol (JDWP) packet
 * declared by the JDWP specification.
 *
 */
public abstract class JdwpPacket {
	/** General JDWP constants. */
	public static final byte FLAG_REPLY_PACKET = (byte)0x80;
	protected static final int MIN_PACKET_LENGTH = 11;
	
	/** Map with Strings for flag bits. */
	private static String[] fgFlagStrings = null;

	/** Header fields. */
	protected int fId = 0;
	protected byte fFlags = 0;
	protected byte[] fDataBuf = null;
	
	/**
	 * Set Id.
	 */
	/*package*/ void setId(int id) {
		fId = id;
	}

	/**
	 * @return Returns Id.
	 */
	public int getId() {
		return fId;
	}
	
	/**
	 * Set Flags.
	 */
	/*package*/ void setFlags(byte flags) {
		fFlags = flags;
	}
	
	/**
	 * @return Returns Flags.
	 */
	public byte getFlags() {
		return fFlags;
	}

	/**
	 * @return Returns total length of packet.
	 */
	public int getLength() {
		return MIN_PACKET_LENGTH + getDataLength();
	}
	
	/**
	 * @return Returns length of data in packet.
	 */
	public int getDataLength() {
		return fDataBuf == null ? 0 : fDataBuf.length;
	}
	
	/**
	 * @return Returns data of packet.
	 */
	public byte[] data() {
		return fDataBuf;
	}

	/**
	 * @return Returns DataInputStream with reply data, or an empty stream if there is none.
	 */
	public DataInputStream dataInStream() {
		if (fDataBuf != null) {
			return new DataInputStream(new ByteArrayInputStream(fDataBuf));
		}
		
		return new DataInputStream(new ByteArrayInputStream(new byte[0]));
	}

	/**
	 * Assigns data to packet.
	 */
	public void setData(byte[] data) {
		fDataBuf = data;
	}
	
	/**
	 * Reads header fields that are specific for a type of packet.
	 */
	protected abstract void readSpecificHeaderFields(DataInputStream dataInStream) throws IOException;
	
	/**
	 * Writes header fields that are specific for a type of packet.
	 */
	protected abstract void writeSpecificHeaderFields(DataOutputStream dataOutStream) throws IOException;
	
	/**
	 * Reads complete packet.
	 */
	public static JdwpPacket read(InputStream inStream) throws IOException {
		DataInputStream dataInStream = new DataInputStream(inStream);

		// Read header.
		int packetLength = dataInStream.readInt();
		int id = dataInStream.readInt();
		byte flags = dataInStream.readByte();

		// Determine type: command or reply.
		JdwpPacket packet;
		if ((flags & FLAG_REPLY_PACKET) != 0)
			packet = new JdwpReplyPacket();
		else
			packet = new JdwpCommandPacket();
			
		// Assign generic header fields.
		packet.setId(id);
		packet.setFlags(flags);
			
		// Read specific header fields and data.
		packet.readSpecificHeaderFields(dataInStream);
		if (packetLength - MIN_PACKET_LENGTH > 0) {
			packet.fDataBuf = new byte[packetLength - MIN_PACKET_LENGTH];
			dataInStream.readFully(packet.fDataBuf);
		}
		
		return packet;
	}
	
	/**
	 * Writes complete packet.
	 */
	public void write(OutputStream outStream) throws IOException {
		DataOutputStream dataOutStream = new DataOutputStream(outStream);
		
		writeHeader(dataOutStream);
		writeData(dataOutStream);
	}
	
	/**
	 * Writes header of packet.
	 */
	protected void writeHeader(DataOutputStream dataOutStream) throws IOException {
		dataOutStream.writeInt(getLength());
		dataOutStream.writeInt(getId());
		dataOutStream.writeByte(getFlags());
		writeSpecificHeaderFields(dataOutStream);
	}
	
	/**
	 * Writes data of packet.
	 */
	protected void writeData(DataOutputStream dataOutStream) throws IOException {
		if (fDataBuf != null) {
			dataOutStream.write(fDataBuf);
		}
	}


	/**
	 * Retrieves constant mappings.
	 */
	public static void getConstantMaps() {
		if (fgFlagStrings != null) {
			return;
		}
		
		Field[] fields = JdwpPacket.class.getDeclaredFields();
		fgFlagStrings = new String[8];
		
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			if ((field.getModifiers() & Modifier.PUBLIC) == 0 || (field.getModifiers() & Modifier.STATIC) == 0 || (field.getModifiers() & Modifier.FINAL) == 0) {
				continue;
			}
				
			String name = field.getName();
			if (!name.startsWith("FLAG_")) {//$NON-NLS-1$
				continue;
			}
				
			name = name.substring(5);
			
			try {
				byte value = field.getByte(null);
				
				for (int j = 0; j < fgFlagStrings.length; j++) {
					if ((1 << j & value) != 0) {
						fgFlagStrings[j]= name;
						break;
					}
				}
			} catch (IllegalAccessException e) {
				// Will not occur for own class.
			} catch (IllegalArgumentException e) {
				// Should not occur.
				// We should take care that all public static final constants
				// in this class are bytes.
			}
		}
	}
	
	/**
	 * @return Returns a mapping with string representations of flags.
	 */
	public static String[] getFlagMap() {
		getConstantMaps();
		return fgFlagStrings;
	}
}
