/**
 *    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
 *
 *    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;

/**
 * This class is a Rapid Spanning Tree Protocol
 * Bridge Protocol Data Unit.
 * <!-- CHECKSTYLE IGNORE WriteTag FOR NEXT 1 LINES -->
 * @author alexreimers
 */
public class BPDU extends BasePacket {
    public enum BPDUType {
        CONFIG,
        TOPOLOGY_CHANGE;
    }

    private static final long DEST_MAC = 0x0180c2000000L; // 01-80-c2-00-00-00

    // TODO - check this for RSTP
    private LLC llcHeader;
    private short protocolId = 0;
    private byte version = 0;
    private byte type;
    private byte flags;
    private byte[] rootBridgeId;
    private int rootPathCost;
    private byte[] senderBridgeId; // switch cluster MAC
    private short portId; // port it was transmitted from
    private short messageAge; // 256ths of a second
    private short maxAge; // 256ths of a second
    private short helloTime; // 256ths of a second
    private short forwardDelay; // 256ths of a second

    public BPDU(BPDUType type) {
        rootBridgeId = new byte[8];
        senderBridgeId = new byte[8];

        llcHeader = new LLC();
        llcHeader.setDsap((byte) 0x42);
        llcHeader.setSsap((byte) 0x42);
        llcHeader.setCtrl((byte) 0x03);

        switch (type) {
            case CONFIG:
                this.type = 0x0;
                break;
            case TOPOLOGY_CHANGE:
                this.type = (byte) 0x80; // 1000 0000
                break;
            default:
                this.type = 0;
                break;
        }
    }

    @Override
    public byte[] serialize() {
        byte[] data;
        // TODO check these
        if (type == 0x0) {
            // config
            data = new byte[38];
        } else {
            // topology change
            data = new byte[7]; // LLC + TC notification
        }

        ByteBuffer bb = ByteBuffer.wrap(data);
        // Serialize the LLC header
        byte[] llc = llcHeader.serialize();
        bb.put(llc, 0, llc.length);
        bb.putShort(protocolId);
        bb.put(version);
        bb.put(type);

        if (type == 0x0) {
            bb.put(flags);
            bb.put(rootBridgeId, 0, rootBridgeId.length);
            bb.putInt(rootPathCost);
            bb.put(senderBridgeId, 0, senderBridgeId.length);
            bb.putShort(portId);
            bb.putShort(messageAge);
            bb.putShort(maxAge);
            bb.putShort(helloTime);
            bb.putShort(forwardDelay);
        }

        return data;
    }

    @Override
    public IPacket deserialize(byte[] data, int offset, int length) {
        ByteBuffer bb = ByteBuffer.wrap(data, offset, length);

        // LLC header
        llcHeader.deserialize(data, offset, 3);

        this.protocolId = bb.getShort();
        this.version = bb.get();
        this.type = bb.get();

        // These fields only exist if it's a configuration BPDU
        if (this.type == 0x0) {
            this.flags = bb.get();
            bb.get(rootBridgeId, 0, 6);
            this.rootPathCost = bb.getInt();
            bb.get(this.senderBridgeId, 0, 6);
            this.portId = bb.getShort();
            this.messageAge = bb.getShort();
            this.maxAge = bb.getShort();
            this.helloTime = bb.getShort();
            this.forwardDelay = bb.getShort();
        }
        // TODO should we set other fields to 0?

        return this;
    }

    public long getDestMac() {
        return DEST_MAC;
    }
}
