// 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 OFTableFeaturePropExperimenterVer13 implements OFTableFeaturePropExperimenter {
    private static final Logger logger = LoggerFactory.getLogger(OFTableFeaturePropExperimenterVer13.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 OFTableFeaturePropExperimenterVer13 DEFAULT = new OFTableFeaturePropExperimenterVer13(
        DEFAULT_EXPERIMENTER, DEFAULT_SUBTYPE, DEFAULT_EXPERIMENTER_DATA
    );

    // package private constructor - used by readers, builders, and factory
    OFTableFeaturePropExperimenterVer13(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 0xfffe;
    }

    @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 OFTableFeaturePropExperimenter.Builder createBuilder() {
        return new BuilderWithParent(this);
    }

    static class BuilderWithParent implements OFTableFeaturePropExperimenter.Builder {
        final OFTableFeaturePropExperimenterVer13 parentMessage;

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

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

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

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

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

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

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



        @Override
        public OFTableFeaturePropExperimenter 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 OFTableFeaturePropExperimenterVer13(
                    experimenter,
                    subtype,
                    experimenterData
                );
        }

    }

    static class Builder implements OFTableFeaturePropExperimenter.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 0xfffe;
    }

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

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

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

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

//
        @Override
        public OFTableFeaturePropExperimenter 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 OFTableFeaturePropExperimenterVer13(
                    experimenter,
                    subtype,
                    experimenterData
                );
        }

    }


    final static Reader READER = new Reader();
    static class Reader implements OFMessageReader<OFTableFeaturePropExperimenter> {
        @Override
        public OFTableFeaturePropExperimenter readFrom(ChannelBuffer bb) throws OFParseError {
            int start = bb.readerIndex();
            // fixed value property type == 0xfffe
            short type = bb.readShort();
            if(type != (short) 0xfffe)
                throw new OFParseError("Wrong type: Expected=0xfffe(0xfffe), 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));

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

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

    final static OFTableFeaturePropExperimenterVer13Funnel FUNNEL = new OFTableFeaturePropExperimenterVer13Funnel();
    static class OFTableFeaturePropExperimenterVer13Funnel implements Funnel<OFTableFeaturePropExperimenterVer13> {
        private static final long serialVersionUID = 1L;
        @Override
        public void funnel(OFTableFeaturePropExperimenterVer13 message, PrimitiveSink sink) {
            // fixed value property type = 0xfffe
            sink.putShort((short) 0xfffe);
            // 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<OFTableFeaturePropExperimenterVer13> {
        @Override
        public void write(ChannelBuffer bb, OFTableFeaturePropExperimenterVer13 message) {
            int startIndex = bb.writerIndex();
            // fixed value property type = 0xfffe
            bb.writeShort((short) 0xfffe);
            // 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("OFTableFeaturePropExperimenterVer13(");
        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;
        OFTableFeaturePropExperimenterVer13 other = (OFTableFeaturePropExperimenterVer13) 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;
    }

}
