package cz.vutbr.feec.packets.ttp;

import cz.vutbr.feec.packets.PacketGenerateException;
import cz.vutbr.feec.packets.PacketParseException;
import cz.vutbr.feec.packets.PacketUtils;
import org.apache.commons.lang.builder.ToStringBuilder;

public class FTIPacket extends GeneralTTPHeader {

	private long feedbackTargetPort;
	private int informationStatus;
	private int parameters;
		
	public FTIPacket() {
		super(2);
	}
	
	/**
	 * @param version definuje verzo protokolu
	 * @param packetType definuje typ paketu FTI = 2
	 * @param fbTreeID definuje ID stromu
	 * @param length definuje velikost celeho paketu
	 * @param FTport definuje port na kterém FT prijíma unicast
	 * @param infoStat definuje stav ve kterém se aktuálne FT nachazi
	 * @param param parametry 
	 */
	public FTIPacket(int version, int packetType, long fbTreeID, int length, long FTport, int infoStat, int param){
		
		setVersion(version);
		setPacketType(packetType);
		setFeedbackTreeId(fbTreeID);
		setLength(length);
		setFeedbackTargetPort(FTport);
		setInformationStatus(infoStat);
		setParameters(param);
	}
	/**
	 * Generate buffer of values in FTC header. <i>This method generates 
	 * specific size of bytes into the buffer.</i>
	 * @param resultArray  - memory bytes for generating buffer
	 * @param startPos - starting position in resultArray
	 */
	@Override
	public int generate(byte[] resultArray, int startPos)
	throws PacketGenerateException {
		int length = super.generate(resultArray, startPos);
		length += generateRestFTI(resultArray, startPos+length);
		return length;
	}
	
	private int generateRestFTI(byte[] buffer, int offset){
		
		assert PacketUtils.checkSize(this.getFeedbackTargetPort(), 16);
		assert PacketUtils.checkSize(this.getInformationStatus(), 8);
		assert PacketUtils.checkSize(this.getParameters(), 8);

		
		//adding Feedback target port to buffer
		
		PacketUtils.setOctet2(buffer, offset, this.getFeedbackTargetPort());
		//adding Activation status
		
		PacketUtils.setOctet1(buffer, offset+2, this.getInformationStatus());
		//adding ReservedEnd
		
		PacketUtils.setOctet1(buffer, offset+3, this.getParameters());		
		// zbytek hlavicky zabere celkem 32 bitu
		return 4;
	}
	/**
	 * Parsing FTC header values from buffer. <i>This method takes specific 
	 * number of bytes from buffer and parse them into FTC header values. </i>
	 * @param resultArray  - memory bytes for parsing the values
	 * @param startPos - starting position in resultArray
	 * @param length - length of header
	 */
	@Override
	public int parse(byte[] resultArray, int startPos, int length)
			throws PacketParseException {
		int len = super.parse(resultArray, startPos, length);
		len += this.parseRestFTI(resultArray, startPos, length);
		return len;
	}
	
	
	private int parseRestFTI(byte[] resultArray, int startPos, int length) throws PacketParseException{
			this.setFeedbackTargetPort(PacketUtils.getOctet2(resultArray, 4+ startPos));	
			this.setInformationStatus(PacketUtils.getOctet1(resultArray, 6 + startPos));
			this.setParameters(PacketUtils.getOctet1(resultArray, 7 + startPos));
		
		return 4;
	}

	public long getFeedbackTargetPort() {
		return feedbackTargetPort;
	}

	public void setFeedbackTargetPort(long feedbackTargetPort) {
		this.feedbackTargetPort = feedbackTargetPort;
	}

	public int getInformationStatus() {
		return informationStatus;
	}

	public void setInformationStatus(int informationStatus) {
		this.informationStatus = informationStatus;
	}

	public int getParameters() {
		return parameters;
	}

	public void setParameters(int param) {
		this.parameters = param;
	}
	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return new ToStringBuilder(this).append("activationStatus",
				this.informationStatus).append("feedbackTargetPort",
				this.feedbackTargetPort).append("version", this.getVersion())
				.append("reservedEnd",
						this.parameters).append("packetType",
						this.getPacketType())
				.append("length", this.getLength()).append("feedbackTreeId",
						this.getFeedbackTreeId()).toString();
	}

}
