/**
*    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.packet;

import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Shudong Zhou (shudong.zhou@bigswitch.com)
 *
 */
public class BSN extends BasePacket {
	public static final int BSN_MAGIC = 0x20000604;
	public static final short BSN_VERSION_CURRENT = 0x0;
	public static final short BSN_TYPE_PROBE = 0x1;
	public static final short BSN_TYPE_BDDP  = 0x2;
	public static Map<Short, Class<? extends IPacket>> typeClassMap;
	
    static {
        typeClassMap = new HashMap<Short, Class<? extends IPacket>>();
        typeClassMap.put(BSN_TYPE_PROBE, BSNPROBE.class);
        typeClassMap.put(BSN_TYPE_BDDP, LLDP.class);
    }

	protected short type;
	protected short version;

	public BSN() {
    	version = BSN_VERSION_CURRENT;
	}
	
    public BSN(short type) {
    	this.type = type;
    	version = BSN_VERSION_CURRENT;
    }

    public short getType() {
		return type;
	}

	public BSN setType(short type) {
		this.type = type;
		return this;
	}
	
    public short getVersion() {
		return version;
	}

	public BSN setVersion(short version) {
		this.version = version;
		return this;
	}

    @Override
    public byte[] serialize() {
    	short length = 4 /* magic */ + 2 /* type */ + 2 /* version */;
    	
    	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.putInt(BSN_MAGIC);
        bb.putShort(this.type);
        bb.putShort(this.version);
        if (payloadData != null)
        	bb.put(payloadData);

        if (this.parent != null && this.parent instanceof Ethernet)
            ((Ethernet)this.parent).setEtherType(Ethernet.TYPE_BSN);

        return data;
    }

    @Override
    public IPacket deserialize(byte[] data, int offset, int length) {
        ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        
        int magic = bb.getInt();
        if (magic != BSN_MAGIC) {
        	throw new RuntimeException("Invalid BSN magic " + magic);
        }
        
        this.type = bb.getShort();
        this.version = bb.getShort();
        if (this.version != BSN_VERSION_CURRENT) {
        	throw new RuntimeException(
        			"Invalid BSN packet version " + this.version + ", should be "
        	        + BSN_VERSION_CURRENT);
        }
        
        IPacket payload;
        if (typeClassMap.containsKey(this.type)) {
            Class<? extends IPacket> clazz = typeClassMap.get(this.type);
            try {
                payload = clazz.newInstance();
            } catch (Exception e) {
                throw new RuntimeException("Error parsing payload for BSN packet" + e);
            }
        } else {
            payload = new Data();
        }
        
        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 + version;
        result = prime * result + type;
        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 BSN))
            return false;
        BSN other = (BSN) obj;
        return (type == other.type &&
        		version == other.version);
    }
    
    public String toString() {
    	StringBuffer sb = new StringBuffer("\n");
    	sb.append("BSN packet");
        if (typeClassMap.containsKey(this.type))
        	sb.append(" type: " + typeClassMap.get(this.type).getCanonicalName());
        else
        	sb.append(" type: " + this.type);
        
    	return sb.toString();
    }
}
