package org.projectfloodlight.openflow.types;

import org.jboss.netty.buffer.ChannelBuffer;
import org.projectfloodlight.openflow.exceptions.OFParseError;

import com.google.common.primitives.Shorts;

public class VlanVid implements OFValueType<VlanVid> {

    private static final short VALIDATION_MASK = 0x0FFF;
    private static final short NONE_VAL = 0x0000;
    final static int LENGTH = 2;

    public static final VlanVid NONE = new VlanVid(NONE_VAL);
    public static final VlanVid NO_MASK = new VlanVid((short)0xFFFF);
    public static final VlanVid FULL_MASK = VlanVid.of((short)0x0);

    private final short vid;

    private VlanVid(short vid) {
        this.vid = vid;
    }

    public static VlanVid of(short vid) {
        if(vid == NONE_VAL)
            return NONE;
        else if ((vid & VALIDATION_MASK) != vid)
            throw new IllegalArgumentException("Illegal VLAN VID value: " + vid);
        return new VlanVid(vid);
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof VlanVid))
            return false;
        VlanVid other = (VlanVid)obj;
        if (other.vid != this.vid)
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        int prime = 13873;
        return this.vid * prime;
    }

    @Override
    public String toString() {
        return "0x" + Integer.toHexString(vid);
    }

    public short getValue() {
        return vid;
    }

    @Override
    public int getLength() {
        return LENGTH;
    }


    volatile byte[] bytesCache = null;

    public byte[] getBytes() {
        if (bytesCache == null) {
            synchronized (this) {
                if (bytesCache == null) {
                    bytesCache =
                            new byte[] { (byte) ((vid >>> 8) & 0xFF),
                                         (byte) ((vid >>> 0) & 0xFF) };
                }
            }
        }
        return bytesCache;
    }

    public void write2Bytes(ChannelBuffer c) {
        c.writeShort(this.vid);
    }

    public static VlanVid read2Bytes(ChannelBuffer c) throws OFParseError {
        return VlanVid.of(c.readShort());
    }

    @Override
    public VlanVid applyMask(VlanVid mask) {
        return VlanVid.of((short)(this.vid & mask.vid));
    }

    @Override
    public int compareTo(VlanVid o) {
        return Shorts.compare(vid, o.vid);
    }

}
