/*
	David Tate

	A Message send between BeaconServer and BeaconClient.
	Uses BeaconState to get information about the Beacon
		sending the message.
	Adds 'type' to show the server what action needs to 
		be performed.
*/

import java.net.*;

public class BeaconMessage extends BeaconState {
	protected int type;
	protected Object[] args;
	private final int MAX_ARGUMENTS = 5;

	/* message type statics */
	/* the 'type' is one of these */
	//from server
	public static final int LOGIN                 = 0;
	public static final int END_LOGIN             = 1;
	public static final int LOGOUT					 = 2;
	public static final int USER                  = 3;

	//from other client
	public static final int OPEN  					 = 4;
	public static final int OPEN_RESPONSE 			 = 5;
	public static final int LIST 						 = 6;
	public static final int LIST_FILE 				 = 7;
	public static final int LIST_RESPONSE 			 = 8;
	public static final int END_LIST  				 =	9;
	public static final int GET  						 = 10;
	public static final int SEARCHGET  				 = 11;
	public static final int PUT  						 = 12;
	public static final int CLOSE           		 =	13;
	public static final int CLOSE_RESPONSE        = 14;
	public static final int SEARCH_FILE_FOUND     = 15;
	public static final int SEARCH_FILE_NOT_FOUND = 16;

	//error codes
	public static final int INVALID_USER          = 17;
	public static final int INVALID_TOKEN         = 18;
	public static final int INVALID_FILENAME      = 19;

	//key server codes
	public static final int AUTHENTICATE          = 20;
	public static final int AUTHENTICATE_RESPONSE = 21;
	public static final int VALIDATE              = 22;
	public static final int VALIDATE_RESPONSE     = 23;
	public static final int REVOKE                = 24;
	public static final int REVOKE_RESPONSE       = 25;
	public static final int TOKEN_EXPIRED         = 26;
	public static final int KEYSERVER_INFO        = 27;
	public static final int OK                    = 28;

	BeaconMessage (int type, String name, InetAddress address, int port) {
		super (name, address, port);
		this.type = type;
		args = new Object[1];	//empty array b/c no args passed in.
	}

	BeaconMessage (int type, Object[] arguments, String name, InetAddress address, int port) {
		super (name, address, port);
		this.type = type;
		args = new Object [ arguments.length ];
		for (int i = 0; i < arguments.length; i++)
			args[i] = arguments[i];
	}

	public Object getArg (int index) {
		if (index > args.length)
			return "";
		else
			return args[index];
	}

	public int getType () {
		return (this.type);
	}
	
	public String getTypeString () {
		int type = getType();
		switch (type) {
			case LOGIN:
				return "LOGIN";
			case LOGOUT:
				return "LOGOUT";
			case END_LOGIN:
				return "END_LOGIN";
			case USER:
				return "USER";
			case OPEN:
				return "OPEN";
			case OPEN_RESPONSE:
				return "OPEN_RESPONSE";
			case LIST:
				return "LIST";
			case LIST_FILE:
				return "LIST_FILE";
			case LIST_RESPONSE:
				return "LIST_RESPONSE";
			case END_LIST:
				return "END_LIST";
			case GET:
				return "GET";
			case PUT:
				return "PUT";
			case CLOSE_RESPONSE:
				return "CLOSE_RESPONSE";
			case CLOSE:
				return "CLOSE";
			case SEARCHGET:
				return "SEARCHGET";
			case SEARCH_FILE_FOUND:
				return "SEARCH_FILE_FOUND";
			case SEARCH_FILE_NOT_FOUND:
				return "SEARCH_FILE_NOT_FOUND";
			case INVALID_USER:
				return "INVALID_USER";
			case INVALID_TOKEN:
				return "INVALID_TOKEN";
			case INVALID_FILENAME:
				return "INVALID_FILENAME";
			default:
				return "UNKNOWN";
		}
	}

	public String toString() {
		return (getTypeString() + " " + getName() + " " + getAddress() + " " + getPort() );
	}
}

