/**
*    Copyright 2012, Big Switch Networks, Inc. 
* 
*    Licensed under the Apache License, Version 2.0 (the "License"); you may
*    not use this file except in compliance with the License. You may obtain
*    a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
*    License for the specific language governing permissions and limitations
*    under the License.
**/

/**
 * 
 */
package net.onrc.onos.core.packet;

import java.nio.ByteBuffer;
import java.util.Arrays;
import org.openflow.util.HexString;

/**
 * @author Shudong Zhou (shudong.zhou@bigswitch.com)
 *
 */
public class BSNPROBE extends BasePacket {	
	protected long controllerId;
	protected int sequenceId;
	protected byte[] srcMac;
	protected byte[] dstMac;
	protected long srcSwDpid;
	protected int srcPortNo;

    public BSNPROBE() {
        srcMac = new byte[6];
        dstMac = new byte[6];
    }


	public long getControllerId() {
		return this.controllerId;
	}

	public BSNPROBE setControllerId(long controllerId) {
		this.controllerId = controllerId;
		return this;
	}

	public int getSequenceId() {
		return sequenceId;
	}

	public BSNPROBE setSequenceId(int sequenceId) {
		this.sequenceId = sequenceId;
		return this;
	}
	
    public byte[] getSrcMac() {
        return this.srcMac;
    }

    public BSNPROBE setSrcMac(byte[] srcMac) {
        this.srcMac = srcMac;
        return this;
    }
    
	public byte[] getDstMac() {
		return dstMac;
	}

	public BSNPROBE setDstMac(byte[] dstMac) {
		this.dstMac = dstMac;
		return this;
	}

	public long getSrcSwDpid() {
		return srcSwDpid;
	}

	public BSNPROBE setSrcSwDpid(long srcSwDpid) {
		this.srcSwDpid = srcSwDpid;
		return this;
	}

	public int getSrcPortNo() {
		return srcPortNo;
	}

	public BSNPROBE setSrcPortNo(int srcPortNo) {
		this.srcPortNo = srcPortNo;
		return this;
	}

    @Override
    public byte[] serialize() {
    	short length = 8 /* controllerId */ + 4 /* seqId */
    			+ 12 /* srcMac dstMac */ + 8 /* srcSwDpid */ + 4 /* srcPortNo */;
    	
    	byte[] payloadData = null;
    	if (this.payload != null) {
            payload.setParent(this);
            payloadData = payload.serialize();
            length += payloadData.length;
        }
    
        byte[] data = new byte[length];
        ByteBuffer bb = ByteBuffer.wrap(data);
        bb.putLong(this.controllerId);
        bb.putInt(this.sequenceId);
        bb.put(this.srcMac);
        bb.put(this.dstMac);
        bb.putLong(this.srcSwDpid);
        bb.putInt(this.srcPortNo);
        if (payloadData != null)
        	bb.put(payloadData);

        if (this.parent != null && this.parent instanceof BSN)
            ((BSN)this.parent).setType(BSN.BSN_TYPE_PROBE);

        return data;
    }

    @Override
    public IPacket deserialize(byte[] data, int offset, int length) {
        ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        
        controllerId = bb.getLong();
        sequenceId = bb.getInt();
        bb.get(this.srcMac, 0, 6);
        bb.get(this.dstMac, 0, 6);
        this.srcSwDpid = bb.getLong();
        this.srcPortNo = bb.getInt();
        
        if (bb.hasRemaining()) {
        	this.payload = new Data();
	        this.payload = payload.deserialize(data, bb.position(), bb.limit() - bb.position());
	        this.payload.setParent(this);
        }
        
        return this;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 883;
        int result = super.hashCode();
        result = prime * result + srcMac.hashCode();
        result = prime * result + dstMac.hashCode();
        result = prime * result + (int) (srcSwDpid >> 32) + (int) srcSwDpid;
        result = prime * result + srcPortNo;
        return result;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (!(obj instanceof BSNPROBE))
            return false;
        BSNPROBE other = (BSNPROBE) obj;
        if (!Arrays.equals(srcMac, other.srcMac))
            return false;
        if (!Arrays.equals(dstMac, other.dstMac))
        	return false;
        return (sequenceId == other.sequenceId &&
        	    srcSwDpid == other.srcSwDpid &&
        	    srcPortNo == other.srcPortNo
        	    );
    }
    
    public String toString() {
    	StringBuffer sb = new StringBuffer("\n");
    	sb.append("BSN Probe packet");
    	sb.append("\nSource Mac: ");
    	sb.append(HexString.toHexString(srcMac));
    	sb.append("\nDestination Mac: ");
    	sb.append(HexString.toHexString(dstMac));
    	sb.append("\nSource Switch: ");
    	sb.append(HexString.toHexString(srcSwDpid));
    	sb.append(" port: " + srcPortNo);
    	sb.append("\nSequence No.:" + sequenceId);
    	
    	return sb.toString();
    }
}
