package com.eactive.eai.adapter.socket2.protocol;

import org.apache.mina.common.ByteBuffer;

import com.eactive.eai.adapter.EAIException;
import com.eactive.eai.adapter.socket2.common.CommonLib;

public class ByteMessage {
    protected byte[] value;
    
    public ByteMessage() {    
    	this.value = new byte[0];
    }

    public ByteMessage(byte[] value) {
    	this.value = value;
    }

    public ByteMessage(String value) {
    	this.value = value.getBytes();
    }
    
    public ByteMessage(ByteBuffer buffer) {
    	this.setByteBuffer(buffer);
    }
    
    public byte getByte(int offset) {
    	return this.value[offset];
    }

    public byte[] getBytes() {
        return value;
    }

    public byte[] getBytes(int offset, int length) throws EAIException {
    	if (size() - offset - length < 0) {
    		throw new EAIException("ByteMessage | cannot make negative array size bytes"
    				+ "| size=" + size() + ", offset=" + offset + ", length=" + length + " - " + CommonLib.hexDump(this.value));
    	}

    	byte[] bytes = new byte[length];
    	System.arraycopy(value, offset, bytes, 0, length); 
        return bytes;
    }

    public byte[] getBytes(int offset) {
    	if (size() - offset < 0) {
    		throw new RuntimeException("ByteMessage | cannot make negative array size bytes"
    				+ "| size=" + size() + ", offset=" + offset + " - " + CommonLib.hexDump(this.value));
    	}
    		
    	byte[] bytes = new byte[size()-offset];
    	System.arraycopy(value, offset, bytes, 0, size()-offset); 
        return bytes;
    }
    
    public ByteMessage exclude(int offset, int length) throws EAIException {
		byte[] messageWithoutLl = new byte[size() - length];
		System.arraycopy(getBytes(0, offset), 0, messageWithoutLl, 0, offset);
		System.arraycopy(getBytes(offset + length), 0, messageWithoutLl, offset+length, size()-length-offset);
		return new ByteMessage(messageWithoutLl);
    }
    
    public ByteMessage append(byte b) {
		byte[] sum = new byte[size() + 1];
		System.arraycopy(this.value, 0, sum, 0, size());
		sum[size()] = b;
		this.value = sum;
		return this;
    }

    public ByteMessage append(byte[] bytes) {
		byte[] sum = new byte[size() + bytes.length];
		System.arraycopy(this.value, 0, sum, 0, size());
		System.arraycopy(bytes, 0, sum, size(), bytes.length);
		this.value = sum;
		return this;
    }

    public ByteMessage append(String str) {
    	return append(str.getBytes());
    }
    
    public ByteMessage padding(int length, byte b) throws EAIException {
    	if (length >= size()) {
    		byte[] sum = new byte[length];
    		System.arraycopy(this.value, 0, sum, 0, size());
    		for (int i=0; i<length-size(); i++) {
    			sum[size()+i] = b;
    		}
    		this.value = sum;
    		return this;
    	} else {
    		this.value = getBytes(0, length);
    		return this;
    	}
    }
    
    public String getString() {
        return new String(value);
    }
    
    public void setBytes(byte[] value) {
        this.value = value;
    }

    public void setString(String value) {
        this.value = value.getBytes();
    }
    
    public void setByteBuffer(ByteBuffer buffer) {
    	int mark = buffer.position();
    	this.value = new byte[buffer.remaining()];
    	buffer.get(value);
    	buffer.position(mark);
    }
    
    public ByteBuffer getByteBuffer() {
		ByteBuffer buffer = ByteBuffer.allocate(value.length);
		buffer.put(value);
		buffer.flip();
    	return buffer;
    }
    
    public int size() {
    	if (this.value == null)
    		return 0;
    	return this.value.length;
    }
    
    public String hexDump() {
    	if (size() == 0)
    		return "";
    	return CommonLib.hexDump(this.value);
    }
    
    public String toString() {
    	StringBuilder sb = new StringBuilder();
    	sb.append("ByteMessage[size=" + size() + "]");
    	sb.append(CommonLib.hexDump(this.value, false));
    	return sb.toString();
    }
}
