/****************************************************************************
 * Copyright (c) 2005, 2010 Jan S. Rellermeyer, Systems Group,
 * Department of Computer Science, ETH Zurich 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:
 *    Jan S. Rellermeyer - initial API and implementation
 *    Markus Alexander Kuppe - enhancements and bug fixes
 *    Md.Jamal MohiUddin (Ubiquitous Computing, C-DAC Hyderabad) - IPv6 support
 *    P Sowjanya (Ubiquitous Computing, C-DAC Hyderabad) - IPv6 support
 *
*****************************************************************************/
package ch.ethz.iks.slp.impl;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ProtocolException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;

import ch.ethz.iks.slp.ServiceLocationException;
import ch.ethz.iks.slp.impl.attr.AttributeListVisitor;
import ch.ethz.iks.slp.impl.attr.gen.Parser;
import ch.ethz.iks.slp.impl.attr.gen.ParserException;
import ch.ethz.iks.slp.impl.attr.gen.Rule;

/**
 * base class for all messages that the SLP framework uses.
 * 
 * @author Jan S. Rellermeyer, ETH Zurich
 * @since 0.1
 */
public abstract class SLPMessage {

	/**
	 * the <code>Locale</code> of the message.
	 */
	Locale locale;

	/**
	 * the funcID encodes the message type.
	 */
	byte funcID;

	/**
	 * the transaction ID.
	 */
	short xid;

	/**
	 * the sender or receiver address.
	 */
	InetAddress address;

	/**
	 * the sender or receiver port.
	 */
	int port;

	/**
	 * true if the message was processed or will be sent via TCP
	 */
	boolean tcp;

	/**
	 * true if the message came in or will go out by multicast.
	 */
	boolean multicast;


	/**
	 * the message version according to RFC 2608, Version = 2.
	 */
	public static final byte VERSION = 2;
	
	/**
	 * the message funcID values according to RFC 2608, Service Request = 1.
	 */
	public static final byte SRVRQST = 1;

	/**
	 * the message funcID values according to RFC 2608, Service Reply = 2.
	 */
	public static final byte SRVRPLY = 2;

	/**
	 * the message funcID values according to RFC 2608, Service Registration =
	 * 3.
	 */
	public static final byte SRVREG = 3;

	/**
	 * the message funcID values according to RFC 2608, Service Deregistration =
	 * 4.
	 */
	public static final byte SRVDEREG = 4;

	/**
	 * the message funcID values according to RFC 2608, Service Acknowledgement =
	 * 5.
	 */
	public static final byte SRVACK = 5;

	/**
	 * the message funcID values according to RFC 2608, Attribute Request = 6.
	 */
	public static final byte ATTRRQST = 6;

	/**
	 * the message funcID values according to RFC 2608, Attribute Reply = 7.
	 */
	public static final byte ATTRRPLY = 7;

	/**
	 * the message funcID values according to RFC 2608, DA Advertisement = 8.
	 */
	public static final byte DAADVERT = 8;

	/**
	 * the message funcID values according to RFC 2608, Service Type Request =
	 * 9.
	 */
	public static final byte SRVTYPERQST = 9;

	/**
	 * the message funcID values according to RFC 2608, Service Type Reply = 10.
	 */
	public static final byte SRVTYPERPLY = 10;

	/**
	 * the message funcID values according to RFC 2608, SA Advertisement = 11.
	 */
	public static final byte SAADVERT = 11;

	/**
	 * used for reverse lookup of funcID values to have nicer debug messages.
	 */
	private static final String[] TYPES = { "NULL", "SRVRQST", "SRVPLY",
			"SRVREG", "SRVDEREG", "SRVACK", "ATTRRQST", "ATTRRPLY", "DAADVERT",
			"SRVTYPERQST", "SRVTYPERPLY", "SAADVERT" };

	/**
	 * get the bytes from a SLPMessage. Processes the header and then calls the
	 * getBody() method of the implementing subclass.
	 * 
	 * @return an array of bytes encoding the SLPMessage.
	 * @throws IOException
	 * @throws ServiceLocationException
	 *             in case of IOExceptions.
	 */
	private void writeHeader(final DataOutputStream out)
			throws IOException {
		byte flags = 0;
		if (funcID == SRVREG) {
			flags |= 0x40;
		}
		if (multicast) {
			flags |= 0x20;
		}
		int msgSize = getSize();
		if (!tcp && msgSize > SLPCore.CONFIG.getMTU()) {
			flags |= 0x80;
		}
		out.write(VERSION);
		out.write(funcID);
		out.write((byte) ((msgSize) >> 16));
		out.write((byte) (((msgSize) >> 8) & 0xFF));
		out.write((byte) ((msgSize) & 0xFF));
		out.write(flags);
		out.write(0);
		out.write(0);
		out.write(0);
		out.write(0);
		out.writeShort(xid);
		out.writeUTF(locale.getLanguage());
	}

	/**
	 * 
	 */
	protected abstract void writeTo(final DataOutputStream out) throws IOException;

	/**
	 * 
	 */
	byte[] getBytes() throws IOException {
		final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
		final DataOutputStream out = new DataOutputStream(bytes);
		writeHeader(out);
		writeTo(out);
		return bytes.toByteArray();
	}

	/**
	 * The RFC 2608 SLP message header:
	 * 
	 * <pre>
	 *                   0                   1                   2                   3
	 *                   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *                  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *                  |    Version    |  Function-ID  |            Length             |
	 *                  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *                  | Length, contd.|O|F|R|       reserved          |Next Ext Offset|
	 *                  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *                  |  Next Extension Offset, contd.|              XID              |
	 *                  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *                  |      Language Tag Length      |         Language Tag          \
	 *                  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 * </pre>
	 * 
	 * This method parses the header and then delegates the creation of the
	 * corresponding SLPMessage to the subclass that matches the funcID.
	 * 
	 * @param senderAddr
	 *            the address of the message sender.
	 * @param senderPort
	 *            the port of the message sender.
	 * @param data
	 *            the raw bytes of the message
	 * @param len
	 *            the length of the byte array.
	 * @param tcp
	 *            true if the message was received via TCP, false otherwise.
	 * @return a SLPMessage of the matching subtype.
	 * @throws ServiceLocationException
	 *             in case of any parsing errors.
	 */
	static SLPMessage parse(final InetAddress senderAddr, final int senderPort,
			final DataInputStream in, final boolean tcp)
			throws ServiceLocationException, ProtocolException {
		try {
			final int version = in.readByte(); // version
			if (version != VERSION) {
				in.readByte(); // funcID
				final int length = in.readShort();
				byte[] drop = new byte[length - 4];
				in.readFully(drop);
				SLPCore.platform.logWarning("Dropped SLPv" + version + " message from "
							+ senderAddr + ":" + senderPort);
			}
			final byte funcID = in.readByte(); // funcID
			final int length = readInt(in, 3);

			// slpFlags
			final byte flags = (byte) (in.readShort() >> 8);

			if (!tcp && (flags & 0x80) != 0) {
				throw new ProtocolException();
			}

			// we don't process extensions, we simply ignore them
			readInt(in, 3); // extOffset
			final short xid = in.readShort(); // XID
			final Locale locale = new Locale(in.readUTF(), ""); // Locale

			final SLPMessage msg;

			// decide on the type of the message
			switch (funcID) {
			case DAADVERT:
				msg = new DAAdvertisement(in);
				break;
			case SRVRQST:
				msg = new ServiceRequest(in);
				break;
			case SRVRPLY:
				msg = new ServiceReply(in);
				break;
			case ATTRRQST:
				msg = new AttributeRequest(in);
				break;
			case ATTRRPLY:
				msg = new AttributeReply(in);
				break;
			case SRVREG:
				msg = new ServiceRegistration(in);
				break;
			case SRVDEREG:
				msg = new ServiceDeregistration(in);
				break;
			case SRVACK:
				msg = new ServiceAcknowledgement(in);
				break;
			case SRVTYPERQST:
				msg = new ServiceTypeRequest(in);
				break;
			case SRVTYPERPLY:
				msg = new ServiceTypeReply(in);
				break;
			default:
				throw new ServiceLocationException(
						ServiceLocationException.PARSE_ERROR, "Message type "
								+ getType(funcID) + " not supported");
			}

			// set the fields
			msg.address = senderAddr;
			msg.port = senderPort;
			msg.tcp = tcp;
			msg.multicast = ((flags & 0x2000) >> 13) == 1 ? true : false;
			msg.xid = xid;
			msg.funcID = funcID;
			msg.locale = locale;
			if (msg.getSize() != length) {
				SLPCore.platform.logError("Length of " + msg + " should be " + length + ", read "
								+ msg.getSize());
//				throw new ServiceLocationException(
//						ServiceLocationException.INTERNAL_SYSTEM_ERROR,
//						"Length of " + msg + " should be " + length + ", read "
//								+ msg.getSize());
			}
			return msg;
		} catch (ProtocolException pe) {
			throw pe;
		} catch (IOException ioe) {
			SLPCore.platform.logError("Network Error", ioe);
			throw new ServiceLocationException(
					ServiceLocationException.NETWORK_ERROR, ioe.getMessage());
		}
	}

	/**
	 * 
	 * @return
	 */
	protected int getHeaderSize() {
		return 14 + locale.getLanguage().length();
	}

	/**
	 * 
	 * @return
	 */
	protected abstract int getSize();

	/**
	 * Get a string representation of the message. Overridden by message
	 * subtypes.
	 * 
	 * @return a String.
	 */
	public String toString() {
		final StringBuffer buffer = new StringBuffer();
		buffer.append(getType(funcID) + " - ");
		buffer.append("xid=" + xid);
		buffer.append(", locale=" + locale);
		return buffer.toString();
	}

	/**
	 * returns the string value of the message type, catches the case where an
	 * unsupported message has been received.
	 * 
	 * @param type
	 *            the type.
	 * @return the type as String.
	 */
	static String getType(final int type) {
		if (type > -1 && type < 12) {
			return TYPES[type];
		}
		return String.valueOf(type + " - UNSUPPORTED");
	}

	/**
	 * parse a numerical value that can be spanned over multiple bytes.
	 * 
	 * @param input
	 *            the data input stream.
	 * @param len
	 *            the number of bytes to read.
	 * @return the int value.
	 * @throws ServiceLocationException
	 *             in case of IO errors.
	 */
	private static int readInt(final DataInputStream input, final int len)
			throws ServiceLocationException {
		try {
			int value = 0;
			for (int i = 0; i < len; i++) {
				value <<= 8;
				value += input.readByte() & 0xff;
			}
			return value;
		} catch (IOException ioe) {
			throw new ServiceLocationException(
					ServiceLocationException.PARSE_ERROR, ioe.getMessage());
		}
	}

	/**
	 * transforms a Java list to string list.
	 * 
	 * @param list
	 *            the list
	 * @param delim
	 *            the delimiter
	 * @return the String list.
	 */
	static String listToString(final List list, final String delim) {
		if (list == null || list.size() == 0) {
			return "";
		} else if (list.size() == 1) {
			return list.get(0).toString();
		} else {
			final StringBuffer buffer = new StringBuffer();
			final Object[] elements = list.toArray();
			for (int i = 0; i < elements.length - 1; i++) {
				buffer.append(elements[i]);
				buffer.append(delim);
			}
			buffer.append(elements[elements.length - 1]);
			return buffer.toString();
		}
	}

	/**
	 * transforms a string list to Java List.
	 * 
	 * @param str
	 *            the String list
	 * @param delim
	 *            the delimiter
	 * @return the List.
	 */
	static List stringToList(final String str, final String delim) {
		List result = new ArrayList();
		StringTokenizer tokenizer = new StringTokenizer(str, delim);
		while (tokenizer.hasMoreTokens()) {
			result.add(tokenizer.nextToken());
		}
		return result;
	}

	/**
	 * 
	 * @param input
	 * @return
	 * @throws ServiceLocationException
	 * 
	 * @author Markus Alexander Kuppe
	 * @since 1.1
	 */
	protected List attributeStringToList(String input) throws ServiceLocationException {
		if("".equals(input)) {
			return new ArrayList();
		}
		Parser parser = new Parser();
		try {
			Rule parse = parser.parse("attr-list", input);
			AttributeListVisitor visitor = new AttributeListVisitor();
			parse.visit(visitor);
			return visitor.getAttributes();
		} catch (IllegalArgumentException e) {
			throw new ServiceLocationException(ServiceLocationException.PARSE_ERROR, e.getMessage());
		} catch (ParserException e) {
			throw new ServiceLocationException(ServiceLocationException.PARSE_ERROR, e.getMessage());
		}
	}

	/**
	 * 
	 * @param input
	 * @return
	 * @throws ServiceLocationException
	 * 
	 * @author Markus Alexander Kuppe
	 * @since 1.1
	 */
	protected List attributeStringToListLiberal(String input) {
		if("".equals(input)) {
			return new ArrayList();
		}
		Parser parser = new Parser();
		Rule rule = null;
		try {
			rule = parser.parse("attr-list", input);
		} catch (IllegalArgumentException e) {
			SLPCore.platform.logError(e.getMessage(), e);
			return new ArrayList();
			// may never happen!!!
		} catch (ParserException e) {
			SLPCore.platform.logTraceDrop(e.getMessage());
			rule = e.getRule();
		}
		AttributeListVisitor visitor = new AttributeListVisitor();
		rule.visit(visitor);
		return visitor.getAttributes();
	}

	/**
	 * Returns the Type of The Request Message
	 * 
	 */
	static byte getMessageType(RequestMessage msg) {
		return msg.funcID;
	}
}
