/**
 *    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.HashMap;
import java.util.Map;

// CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
/**
 * @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 final Map<Short, Class<? extends IPacket>> TYPE_CLASS_MAP;

    static {
        TYPE_CLASS_MAP = new HashMap<Short, Class<? extends IPacket>>();
        TYPE_CLASS_MAP.put(BSN_TYPE_PROBE, BSNPROBE.class);
        TYPE_CLASS_MAP.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 (TYPE_CLASS_MAP.containsKey(this.type)) {
            Class<? extends IPacket> clazz = TYPE_CLASS_MAP.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);
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer("\n");
        sb.append("BSN packet");
        if (TYPE_CLASS_MAP.containsKey(this.type)) {
            sb.append(" type: " + TYPE_CLASS_MAP.get(this.type).getCanonicalName());
        } else {
            sb.append(" type: " + this.type);
        }


        return sb.toString();
    }
}
