package madynes.flowoid.exporter;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;


/** RFC3954 5.3 > Record N - Field Value M */
public abstract class DataField implements Exportable {
	private TemplateField template;

	@Override
	public short getTotalLength() {
		return getTemplate().getLength();
	}
	
	@Override
	public ArrayList<Byte> toBytes() throws TemplateMismatchException {
		ArrayList<Byte> bytes = getArrayListValue();
		
		if(bytes.size() != getTemplate().getLength())
			throw new TemplateMismatchException("The bytes count is not in adequation"
					+ " with the field template.");

    	return bytes;
	}

	/**
	 * Returns a byte buffer with the length defined in the associated template
	 * field. Please use it with the getValue() implementation to avoid to return
	 * a wrong size value. 
	 * 
	 * @return byte buffer with the correct size 
	 */
	public ByteBuffer getByteBuffer() {
    	ByteBuffer value = ByteBuffer.allocate(getTemplate().getLength());
    	value.order(ByteOrder.BIG_ENDIAN);
    	
    	return value;
	}
	
	/**
	 * Returns the value in ArrayList format, needed by toBytes().
	 * 
	 * @return value in ArrayList format
	 */
	public ArrayList<Byte> getArrayListValue() {
		ArrayList<Byte> bytes = new ArrayList<Byte>();
		
    	for(byte b : getValue().array()) {
    		bytes.add((Byte) b);
    	}
    	
    	return bytes;
	}

	/**
	 * Returns the template associated to this field.
	 * 
	 * @return template associated
	 */
	public TemplateField getTemplate() {
		return template;
	}
	
	/**
	 * Sets the associated template.
	 * 
	 * @param template template associated
	 */
	public void setTemplate(TemplateField template) {
		this.template = template;
	}
	
	/**
	 * Returns the current value.
	 * 
	 * @return current value
	 */
	public abstract ByteBuffer getValue();
	
	/**
	 * Allows the implementation class to make stuff when it's
	 * the first packet.
	 * 
	 * @param headers first sniffed headers packet for this record
	 */
	public abstract void onInit(byte[] headers);
	
	/**
	 * Allows the implementation class to make stuff when a new
	 * packet is recognized.
	 * 
	 * @param headers last sniffed packet
	 */
	public abstract void onUpdate(byte[] headers);
	
	/**
	 * Allows the implementation class to make stuff when the
	 * Export Packet is created. 
	 * 
	 * @param headers See DataRecord.getLastHeaders()
	 */
	public abstract void onExport(byte[] headers);
}
