package protocolP2P;
import protocolP2P.Payload;
import tools.HostItem;
import tools.BytesArrayTools;
import localException.SizeError;
import localException.InternalError;
import localException.TransmissionError;
import localException.ProtocolError;

/** Representation of payload for ratio request.
 * @author	Louis Royer
 * @author	Flavien Haas
 * @author	JS Auge
 * @version	1.0
 */
public class RatioRequest extends Payload {
	private HostItem hostItem;
	private static final int HOSTNAME_START_POSITION = PAYLOAD_START_POSITION + 2;

	/** Constructor with hostItem (typically used by client/server)
	 * @param hostItem	Host to get ratio of.
	 * @throws	InternalError
	 */
	public RatioRequest(HostItem hostItem) throws InternalError {
		super(RequestResponseCode.RATIO_REQUEST);
		this.hostItem = hostItem;
	}
	
	/** Constructor (typically used by tracker) with a byte[] parameter containing the Packet received.
	 * @param packet	the full Packet received
	 * @throws	SizeError
	 * @throws	InternalError
	 * @throws	ProtocolError
	 * @throws	TransmissionError
	 */
	protected RatioRequest(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError {
		super(packet);
		int size = getPayloadSize(packet);
		int port = BytesArrayTools.readInt16Bits(packet, PAYLOAD_START_POSITION);
		String hostname = BytesArrayTools.readString(packet, HOSTNAME_START_POSITION, size - HOSTNAME_START_POSITION + PAYLOAD_START_POSITION);
		hostItem = new HostItem(hostname, port);
	}

	/** Returns a byte[] containing Packet with padding.
	 * This Packet is still incomplete and should not be send directly.
	 * ProtocolP2PPacket will use this method to generate the complete Packet.
	 * @return Packet with padding
	 * @throws	InternalError
	 */
	protected byte[] toPacket() throws InternalError {
		String hostname = hostItem.getHostname();
		// compute total size
		int size = HOSTNAME_START_POSITION + hostname.length();
		byte[] packet = new byte[size]; // java initialize all to zero
		// set request/response code
		packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
		// set Payload size
		setPayloadSize(size - PAYLOAD_START_POSITION, packet);
		// write port to Packet
		try {
			BytesArrayTools.write16Bits(packet, PAYLOAD_START_POSITION, hostItem.getPort());
		} catch (SizeError e) {
			throw new InternalError();
		}
		// write hostname to Packet
		BytesArrayTools.write(packet, hostname, HOSTNAME_START_POSITION);
		return packet;
	}

	/** HostItem getter.
	 * @return	hostItem
	 */
	public HostItem getHostItem() {
		return hostItem;
	}

}
