// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
// Copyright (c) 2011, 2012 Open Networking Foundation
// Copyright (c) 2012, 2013 Big Switch Networks, Inc.
// This library was generated by the LoxiGen Compiler.
// See the file LICENSE.txt which should have been included in the source distribution

// Automatically generated by LOXI from template of_class.java
// Do not modify

package org.projectfloodlight.openflow.protocol.ver13;

import org.projectfloodlight.openflow.protocol.*;
import org.projectfloodlight.openflow.protocol.action.*;
import org.projectfloodlight.openflow.protocol.actionid.*;
import org.projectfloodlight.openflow.protocol.bsntlv.*;
import org.projectfloodlight.openflow.protocol.errormsg.*;
import org.projectfloodlight.openflow.protocol.meterband.*;
import org.projectfloodlight.openflow.protocol.instruction.*;
import org.projectfloodlight.openflow.protocol.instructionid.*;
import org.projectfloodlight.openflow.protocol.match.*;
import org.projectfloodlight.openflow.protocol.oxm.*;
import org.projectfloodlight.openflow.protocol.queueprop.*;
import org.projectfloodlight.openflow.types.*;
import org.projectfloodlight.openflow.util.*;
import org.projectfloodlight.openflow.exceptions.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Set;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.common.hash.PrimitiveSink;
import com.google.common.hash.Funnel;
import java.util.Arrays;

class OFTableFeaturePropExperimenterMissVer13 implements OFTableFeaturePropExperimenterMiss {
    private static final Logger logger = LoggerFactory.getLogger(OFTableFeaturePropExperimenterMissVer13.class);
    // version: 1.3
    final static byte WIRE_VERSION = 4;
    final static int MINIMUM_LENGTH = 12;

        private final static long DEFAULT_EXPERIMENTER = 0x0L;
        private final static long DEFAULT_SUBTYPE = 0x0L;
        private final static byte[] DEFAULT_EXPERIMENTER_DATA = new byte[0];

    // OF message fields
    private final long experimenter;
    private final long subtype;
    private final byte[] experimenterData;
//
    // Immutable default instance
    final static OFTableFeaturePropExperimenterMissVer13 DEFAULT = new OFTableFeaturePropExperimenterMissVer13(
        DEFAULT_EXPERIMENTER, DEFAULT_SUBTYPE, DEFAULT_EXPERIMENTER_DATA
    );

    // package private constructor - used by readers, builders, and factory
    OFTableFeaturePropExperimenterMissVer13(long experimenter, long subtype, byte[] experimenterData) {
        this.experimenter = experimenter;
        this.subtype = subtype;
        this.experimenterData = experimenterData;
    }

    // Accessors for OF message fields
    @Override
    public int getType() {
        return 0xffff;
    }

    @Override
    public long getExperimenter() {
        return experimenter;
    }

    @Override
    public long getSubtype() {
        return subtype;
    }

    @Override
    public byte[] getExperimenterData() {
        return experimenterData;
    }

    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_13;
    }



    public OFTableFeaturePropExperimenterMiss.Builder createBuilder() {
        return new BuilderWithParent(this);
    }

    static class BuilderWithParent implements OFTableFeaturePropExperimenterMiss.Builder {
        final OFTableFeaturePropExperimenterMissVer13 parentMessage;

        // OF message fields
        private boolean experimenterSet;
        private long experimenter;
        private boolean subtypeSet;
        private long subtype;
        private boolean experimenterDataSet;
        private byte[] experimenterData;

        BuilderWithParent(OFTableFeaturePropExperimenterMissVer13 parentMessage) {
            this.parentMessage = parentMessage;
        }

    @Override
    public int getType() {
        return 0xffff;
    }

    @Override
    public long getExperimenter() {
        return experimenter;
    }

    @Override
    public OFTableFeaturePropExperimenterMiss.Builder setExperimenter(long experimenter) {
        this.experimenter = experimenter;
        this.experimenterSet = true;
        return this;
    }
    @Override
    public long getSubtype() {
        return subtype;
    }

    @Override
    public OFTableFeaturePropExperimenterMiss.Builder setSubtype(long subtype) {
        this.subtype = subtype;
        this.subtypeSet = true;
        return this;
    }
    @Override
    public byte[] getExperimenterData() {
        return experimenterData;
    }

    @Override
    public OFTableFeaturePropExperimenterMiss.Builder setExperimenterData(byte[] experimenterData) {
        this.experimenterData = experimenterData;
        this.experimenterDataSet = true;
        return this;
    }
    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_13;
    }



        @Override
        public OFTableFeaturePropExperimenterMiss build() {
                long experimenter = this.experimenterSet ? this.experimenter : parentMessage.experimenter;
                long subtype = this.subtypeSet ? this.subtype : parentMessage.subtype;
                byte[] experimenterData = this.experimenterDataSet ? this.experimenterData : parentMessage.experimenterData;
                if(experimenterData == null)
                    throw new NullPointerException("Property experimenterData must not be null");

                //
                return new OFTableFeaturePropExperimenterMissVer13(
                    experimenter,
                    subtype,
                    experimenterData
                );
        }

    }

    static class Builder implements OFTableFeaturePropExperimenterMiss.Builder {
        // OF message fields
        private boolean experimenterSet;
        private long experimenter;
        private boolean subtypeSet;
        private long subtype;
        private boolean experimenterDataSet;
        private byte[] experimenterData;

    @Override
    public int getType() {
        return 0xffff;
    }

    @Override
    public long getExperimenter() {
        return experimenter;
    }

    @Override
    public OFTableFeaturePropExperimenterMiss.Builder setExperimenter(long experimenter) {
        this.experimenter = experimenter;
        this.experimenterSet = true;
        return this;
    }
    @Override
    public long getSubtype() {
        return subtype;
    }

    @Override
    public OFTableFeaturePropExperimenterMiss.Builder setSubtype(long subtype) {
        this.subtype = subtype;
        this.subtypeSet = true;
        return this;
    }
    @Override
    public byte[] getExperimenterData() {
        return experimenterData;
    }

    @Override
    public OFTableFeaturePropExperimenterMiss.Builder setExperimenterData(byte[] experimenterData) {
        this.experimenterData = experimenterData;
        this.experimenterDataSet = true;
        return this;
    }
    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_13;
    }

//
        @Override
        public OFTableFeaturePropExperimenterMiss build() {
            long experimenter = this.experimenterSet ? this.experimenter : DEFAULT_EXPERIMENTER;
            long subtype = this.subtypeSet ? this.subtype : DEFAULT_SUBTYPE;
            byte[] experimenterData = this.experimenterDataSet ? this.experimenterData : DEFAULT_EXPERIMENTER_DATA;
            if(experimenterData == null)
                throw new NullPointerException("Property experimenterData must not be null");


            return new OFTableFeaturePropExperimenterMissVer13(
                    experimenter,
                    subtype,
                    experimenterData
                );
        }

    }


    final static Reader READER = new Reader();
    static class Reader implements OFMessageReader<OFTableFeaturePropExperimenterMiss> {
        @Override
        public OFTableFeaturePropExperimenterMiss readFrom(ChannelBuffer bb) throws OFParseError {
            int start = bb.readerIndex();
            // fixed value property type == 0xffff
            short type = bb.readShort();
            if(type != (short) 0xffff)
                throw new OFParseError("Wrong type: Expected=0xffff(0xffff), got="+type);
            int length = U16.f(bb.readShort());
            if(length < MINIMUM_LENGTH)
                throw new OFParseError("Wrong length: Expected to be >= " + MINIMUM_LENGTH + ", was: " + length);
            if(bb.readableBytes() + (bb.readerIndex() - start) < length) {
                // Buffer does not have all data yet
                bb.readerIndex(start);
                return null;
            }
            if(logger.isTraceEnabled())
                logger.trace("readFrom - length={}", length);
            long experimenter = U32.f(bb.readInt());
            long subtype = U32.f(bb.readInt());
            byte[] experimenterData = ChannelUtils.readBytes(bb, length - (bb.readerIndex() - start));

            OFTableFeaturePropExperimenterMissVer13 tableFeaturePropExperimenterMissVer13 = new OFTableFeaturePropExperimenterMissVer13(
                    experimenter,
                      subtype,
                      experimenterData
                    );
            if(logger.isTraceEnabled())
                logger.trace("readFrom - read={}", tableFeaturePropExperimenterMissVer13);
            return tableFeaturePropExperimenterMissVer13;
        }
    }

    public void putTo(PrimitiveSink sink) {
        FUNNEL.funnel(this, sink);
    }

    final static OFTableFeaturePropExperimenterMissVer13Funnel FUNNEL = new OFTableFeaturePropExperimenterMissVer13Funnel();
    static class OFTableFeaturePropExperimenterMissVer13Funnel implements Funnel<OFTableFeaturePropExperimenterMissVer13> {
        private static final long serialVersionUID = 1L;
        @Override
        public void funnel(OFTableFeaturePropExperimenterMissVer13 message, PrimitiveSink sink) {
            // fixed value property type = 0xffff
            sink.putShort((short) 0xffff);
            // FIXME: skip funnel of length
            sink.putLong(message.experimenter);
            sink.putLong(message.subtype);
            sink.putBytes(message.experimenterData);
        }
    }


    public void writeTo(ChannelBuffer bb) {
        WRITER.write(bb, this);
    }

    final static Writer WRITER = new Writer();
    static class Writer implements OFMessageWriter<OFTableFeaturePropExperimenterMissVer13> {
        @Override
        public void write(ChannelBuffer bb, OFTableFeaturePropExperimenterMissVer13 message) {
            int startIndex = bb.writerIndex();
            // fixed value property type = 0xffff
            bb.writeShort((short) 0xffff);
            // length is length of variable message, will be updated at the end
            int lengthIndex = bb.writerIndex();
            bb.writeShort(U16.t(0));

            bb.writeInt(U32.t(message.experimenter));
            bb.writeInt(U32.t(message.subtype));
            bb.writeBytes(message.experimenterData);

            // update length field
            int length = bb.writerIndex() - startIndex;
            bb.setShort(lengthIndex, length);

        }
    }

    @Override
    public String toString() {
        StringBuilder b = new StringBuilder("OFTableFeaturePropExperimenterMissVer13(");
        b.append("experimenter=").append(experimenter);
        b.append(", ");
        b.append("subtype=").append(subtype);
        b.append(", ");
        b.append("experimenterData=").append(Arrays.toString(experimenterData));
        b.append(")");
        return b.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        OFTableFeaturePropExperimenterMissVer13 other = (OFTableFeaturePropExperimenterMissVer13) obj;

        if( experimenter != other.experimenter)
            return false;
        if( subtype != other.subtype)
            return false;
        if (!Arrays.equals(experimenterData, other.experimenterData))
                return false;
        return true;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;

        result = prime *  (int) (experimenter ^ (experimenter >>> 32));
        result = prime *  (int) (subtype ^ (subtype >>> 32));
        result = prime * result + Arrays.hashCode(experimenterData);
        return result;
    }

}
