// 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;

class OFAsyncGetReplyVer13 implements OFAsyncGetReply {
    private static final Logger logger = LoggerFactory.getLogger(OFAsyncGetReplyVer13.class);
    // version: 1.3
    final static byte WIRE_VERSION = 4;
    final static int LENGTH = 32;

        private final static long DEFAULT_XID = 0x0L;
        private final static long DEFAULT_PACKET_IN_MASK_EQUAL_MASTER = 0x0L;
        private final static long DEFAULT_PACKET_IN_MASK_SLAVE = 0x0L;
        private final static long DEFAULT_PORT_STATUS_MASK_EQUAL_MASTER = 0x0L;
        private final static long DEFAULT_PORT_STATUS_MASK_SLAVE = 0x0L;
        private final static long DEFAULT_FLOW_REMOVED_MASK_EQUAL_MASTER = 0x0L;
        private final static long DEFAULT_FLOW_REMOVED_MASK_SLAVE = 0x0L;

    // OF message fields
    private final long xid;
    private final long packetInMaskEqualMaster;
    private final long packetInMaskSlave;
    private final long portStatusMaskEqualMaster;
    private final long portStatusMaskSlave;
    private final long flowRemovedMaskEqualMaster;
    private final long flowRemovedMaskSlave;
//
    // Immutable default instance
    final static OFAsyncGetReplyVer13 DEFAULT = new OFAsyncGetReplyVer13(
        DEFAULT_XID, DEFAULT_PACKET_IN_MASK_EQUAL_MASTER, DEFAULT_PACKET_IN_MASK_SLAVE, DEFAULT_PORT_STATUS_MASK_EQUAL_MASTER, DEFAULT_PORT_STATUS_MASK_SLAVE, DEFAULT_FLOW_REMOVED_MASK_EQUAL_MASTER, DEFAULT_FLOW_REMOVED_MASK_SLAVE
    );

    // package private constructor - used by readers, builders, and factory
    OFAsyncGetReplyVer13(long xid, long packetInMaskEqualMaster, long packetInMaskSlave, long portStatusMaskEqualMaster, long portStatusMaskSlave, long flowRemovedMaskEqualMaster, long flowRemovedMaskSlave) {
        this.xid = xid;
        this.packetInMaskEqualMaster = packetInMaskEqualMaster;
        this.packetInMaskSlave = packetInMaskSlave;
        this.portStatusMaskEqualMaster = portStatusMaskEqualMaster;
        this.portStatusMaskSlave = portStatusMaskSlave;
        this.flowRemovedMaskEqualMaster = flowRemovedMaskEqualMaster;
        this.flowRemovedMaskSlave = flowRemovedMaskSlave;
    }

    // Accessors for OF message fields
    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_13;
    }

    @Override
    public OFType getType() {
        return OFType.GET_ASYNC_REPLY;
    }

    @Override
    public long getXid() {
        return xid;
    }

    @Override
    public long getPacketInMaskEqualMaster() {
        return packetInMaskEqualMaster;
    }

    @Override
    public long getPacketInMaskSlave() {
        return packetInMaskSlave;
    }

    @Override
    public long getPortStatusMaskEqualMaster() {
        return portStatusMaskEqualMaster;
    }

    @Override
    public long getPortStatusMaskSlave() {
        return portStatusMaskSlave;
    }

    @Override
    public long getFlowRemovedMaskEqualMaster() {
        return flowRemovedMaskEqualMaster;
    }

    @Override
    public long getFlowRemovedMaskSlave() {
        return flowRemovedMaskSlave;
    }



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

    static class BuilderWithParent implements OFAsyncGetReply.Builder {
        final OFAsyncGetReplyVer13 parentMessage;

        // OF message fields
        private boolean xidSet;
        private long xid;
        private boolean packetInMaskEqualMasterSet;
        private long packetInMaskEqualMaster;
        private boolean packetInMaskSlaveSet;
        private long packetInMaskSlave;
        private boolean portStatusMaskEqualMasterSet;
        private long portStatusMaskEqualMaster;
        private boolean portStatusMaskSlaveSet;
        private long portStatusMaskSlave;
        private boolean flowRemovedMaskEqualMasterSet;
        private long flowRemovedMaskEqualMaster;
        private boolean flowRemovedMaskSlaveSet;
        private long flowRemovedMaskSlave;

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

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

    @Override
    public OFType getType() {
        return OFType.GET_ASYNC_REPLY;
    }

    @Override
    public long getXid() {
        return xid;
    }

    @Override
    public OFAsyncGetReply.Builder setXid(long xid) {
        this.xid = xid;
        this.xidSet = true;
        return this;
    }
    @Override
    public long getPacketInMaskEqualMaster() {
        return packetInMaskEqualMaster;
    }

    @Override
    public OFAsyncGetReply.Builder setPacketInMaskEqualMaster(long packetInMaskEqualMaster) {
        this.packetInMaskEqualMaster = packetInMaskEqualMaster;
        this.packetInMaskEqualMasterSet = true;
        return this;
    }
    @Override
    public long getPacketInMaskSlave() {
        return packetInMaskSlave;
    }

    @Override
    public OFAsyncGetReply.Builder setPacketInMaskSlave(long packetInMaskSlave) {
        this.packetInMaskSlave = packetInMaskSlave;
        this.packetInMaskSlaveSet = true;
        return this;
    }
    @Override
    public long getPortStatusMaskEqualMaster() {
        return portStatusMaskEqualMaster;
    }

    @Override
    public OFAsyncGetReply.Builder setPortStatusMaskEqualMaster(long portStatusMaskEqualMaster) {
        this.portStatusMaskEqualMaster = portStatusMaskEqualMaster;
        this.portStatusMaskEqualMasterSet = true;
        return this;
    }
    @Override
    public long getPortStatusMaskSlave() {
        return portStatusMaskSlave;
    }

    @Override
    public OFAsyncGetReply.Builder setPortStatusMaskSlave(long portStatusMaskSlave) {
        this.portStatusMaskSlave = portStatusMaskSlave;
        this.portStatusMaskSlaveSet = true;
        return this;
    }
    @Override
    public long getFlowRemovedMaskEqualMaster() {
        return flowRemovedMaskEqualMaster;
    }

    @Override
    public OFAsyncGetReply.Builder setFlowRemovedMaskEqualMaster(long flowRemovedMaskEqualMaster) {
        this.flowRemovedMaskEqualMaster = flowRemovedMaskEqualMaster;
        this.flowRemovedMaskEqualMasterSet = true;
        return this;
    }
    @Override
    public long getFlowRemovedMaskSlave() {
        return flowRemovedMaskSlave;
    }

    @Override
    public OFAsyncGetReply.Builder setFlowRemovedMaskSlave(long flowRemovedMaskSlave) {
        this.flowRemovedMaskSlave = flowRemovedMaskSlave;
        this.flowRemovedMaskSlaveSet = true;
        return this;
    }


        @Override
        public OFAsyncGetReply build() {
                long xid = this.xidSet ? this.xid : parentMessage.xid;
                long packetInMaskEqualMaster = this.packetInMaskEqualMasterSet ? this.packetInMaskEqualMaster : parentMessage.packetInMaskEqualMaster;
                long packetInMaskSlave = this.packetInMaskSlaveSet ? this.packetInMaskSlave : parentMessage.packetInMaskSlave;
                long portStatusMaskEqualMaster = this.portStatusMaskEqualMasterSet ? this.portStatusMaskEqualMaster : parentMessage.portStatusMaskEqualMaster;
                long portStatusMaskSlave = this.portStatusMaskSlaveSet ? this.portStatusMaskSlave : parentMessage.portStatusMaskSlave;
                long flowRemovedMaskEqualMaster = this.flowRemovedMaskEqualMasterSet ? this.flowRemovedMaskEqualMaster : parentMessage.flowRemovedMaskEqualMaster;
                long flowRemovedMaskSlave = this.flowRemovedMaskSlaveSet ? this.flowRemovedMaskSlave : parentMessage.flowRemovedMaskSlave;

                //
                return new OFAsyncGetReplyVer13(
                    xid,
                    packetInMaskEqualMaster,
                    packetInMaskSlave,
                    portStatusMaskEqualMaster,
                    portStatusMaskSlave,
                    flowRemovedMaskEqualMaster,
                    flowRemovedMaskSlave
                );
        }

    }

    static class Builder implements OFAsyncGetReply.Builder {
        // OF message fields
        private boolean xidSet;
        private long xid;
        private boolean packetInMaskEqualMasterSet;
        private long packetInMaskEqualMaster;
        private boolean packetInMaskSlaveSet;
        private long packetInMaskSlave;
        private boolean portStatusMaskEqualMasterSet;
        private long portStatusMaskEqualMaster;
        private boolean portStatusMaskSlaveSet;
        private long portStatusMaskSlave;
        private boolean flowRemovedMaskEqualMasterSet;
        private long flowRemovedMaskEqualMaster;
        private boolean flowRemovedMaskSlaveSet;
        private long flowRemovedMaskSlave;

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

    @Override
    public OFType getType() {
        return OFType.GET_ASYNC_REPLY;
    }

    @Override
    public long getXid() {
        return xid;
    }

    @Override
    public OFAsyncGetReply.Builder setXid(long xid) {
        this.xid = xid;
        this.xidSet = true;
        return this;
    }
    @Override
    public long getPacketInMaskEqualMaster() {
        return packetInMaskEqualMaster;
    }

    @Override
    public OFAsyncGetReply.Builder setPacketInMaskEqualMaster(long packetInMaskEqualMaster) {
        this.packetInMaskEqualMaster = packetInMaskEqualMaster;
        this.packetInMaskEqualMasterSet = true;
        return this;
    }
    @Override
    public long getPacketInMaskSlave() {
        return packetInMaskSlave;
    }

    @Override
    public OFAsyncGetReply.Builder setPacketInMaskSlave(long packetInMaskSlave) {
        this.packetInMaskSlave = packetInMaskSlave;
        this.packetInMaskSlaveSet = true;
        return this;
    }
    @Override
    public long getPortStatusMaskEqualMaster() {
        return portStatusMaskEqualMaster;
    }

    @Override
    public OFAsyncGetReply.Builder setPortStatusMaskEqualMaster(long portStatusMaskEqualMaster) {
        this.portStatusMaskEqualMaster = portStatusMaskEqualMaster;
        this.portStatusMaskEqualMasterSet = true;
        return this;
    }
    @Override
    public long getPortStatusMaskSlave() {
        return portStatusMaskSlave;
    }

    @Override
    public OFAsyncGetReply.Builder setPortStatusMaskSlave(long portStatusMaskSlave) {
        this.portStatusMaskSlave = portStatusMaskSlave;
        this.portStatusMaskSlaveSet = true;
        return this;
    }
    @Override
    public long getFlowRemovedMaskEqualMaster() {
        return flowRemovedMaskEqualMaster;
    }

    @Override
    public OFAsyncGetReply.Builder setFlowRemovedMaskEqualMaster(long flowRemovedMaskEqualMaster) {
        this.flowRemovedMaskEqualMaster = flowRemovedMaskEqualMaster;
        this.flowRemovedMaskEqualMasterSet = true;
        return this;
    }
    @Override
    public long getFlowRemovedMaskSlave() {
        return flowRemovedMaskSlave;
    }

    @Override
    public OFAsyncGetReply.Builder setFlowRemovedMaskSlave(long flowRemovedMaskSlave) {
        this.flowRemovedMaskSlave = flowRemovedMaskSlave;
        this.flowRemovedMaskSlaveSet = true;
        return this;
    }
//
        @Override
        public OFAsyncGetReply build() {
            long xid = this.xidSet ? this.xid : DEFAULT_XID;
            long packetInMaskEqualMaster = this.packetInMaskEqualMasterSet ? this.packetInMaskEqualMaster : DEFAULT_PACKET_IN_MASK_EQUAL_MASTER;
            long packetInMaskSlave = this.packetInMaskSlaveSet ? this.packetInMaskSlave : DEFAULT_PACKET_IN_MASK_SLAVE;
            long portStatusMaskEqualMaster = this.portStatusMaskEqualMasterSet ? this.portStatusMaskEqualMaster : DEFAULT_PORT_STATUS_MASK_EQUAL_MASTER;
            long portStatusMaskSlave = this.portStatusMaskSlaveSet ? this.portStatusMaskSlave : DEFAULT_PORT_STATUS_MASK_SLAVE;
            long flowRemovedMaskEqualMaster = this.flowRemovedMaskEqualMasterSet ? this.flowRemovedMaskEqualMaster : DEFAULT_FLOW_REMOVED_MASK_EQUAL_MASTER;
            long flowRemovedMaskSlave = this.flowRemovedMaskSlaveSet ? this.flowRemovedMaskSlave : DEFAULT_FLOW_REMOVED_MASK_SLAVE;


            return new OFAsyncGetReplyVer13(
                    xid,
                    packetInMaskEqualMaster,
                    packetInMaskSlave,
                    portStatusMaskEqualMaster,
                    portStatusMaskSlave,
                    flowRemovedMaskEqualMaster,
                    flowRemovedMaskSlave
                );
        }

    }


    final static Reader READER = new Reader();
    static class Reader implements OFMessageReader<OFAsyncGetReply> {
        @Override
        public OFAsyncGetReply readFrom(ChannelBuffer bb) throws OFParseError {
            int start = bb.readerIndex();
            // fixed value property version == 4
            byte version = bb.readByte();
            if(version != (byte) 0x4)
                throw new OFParseError("Wrong version: Expected=OFVersion.OF_13(4), got="+version);
            // fixed value property type == 27
            byte type = bb.readByte();
            if(type != (byte) 0x1b)
                throw new OFParseError("Wrong type: Expected=OFType.GET_ASYNC_REPLY(27), got="+type);
            int length = U16.f(bb.readShort());
            if(length != 32)
                throw new OFParseError("Wrong length: Expected=32(32), got="+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 xid = U32.f(bb.readInt());
            long packetInMaskEqualMaster = U32.f(bb.readInt());
            long packetInMaskSlave = U32.f(bb.readInt());
            long portStatusMaskEqualMaster = U32.f(bb.readInt());
            long portStatusMaskSlave = U32.f(bb.readInt());
            long flowRemovedMaskEqualMaster = U32.f(bb.readInt());
            long flowRemovedMaskSlave = U32.f(bb.readInt());

            OFAsyncGetReplyVer13 asyncGetReplyVer13 = new OFAsyncGetReplyVer13(
                    xid,
                      packetInMaskEqualMaster,
                      packetInMaskSlave,
                      portStatusMaskEqualMaster,
                      portStatusMaskSlave,
                      flowRemovedMaskEqualMaster,
                      flowRemovedMaskSlave
                    );
            if(logger.isTraceEnabled())
                logger.trace("readFrom - read={}", asyncGetReplyVer13);
            return asyncGetReplyVer13;
        }
    }

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

    final static OFAsyncGetReplyVer13Funnel FUNNEL = new OFAsyncGetReplyVer13Funnel();
    static class OFAsyncGetReplyVer13Funnel implements Funnel<OFAsyncGetReplyVer13> {
        private static final long serialVersionUID = 1L;
        @Override
        public void funnel(OFAsyncGetReplyVer13 message, PrimitiveSink sink) {
            // fixed value property version = 4
            sink.putByte((byte) 0x4);
            // fixed value property type = 27
            sink.putByte((byte) 0x1b);
            // fixed value property length = 32
            sink.putShort((short) 0x20);
            sink.putLong(message.xid);
            sink.putLong(message.packetInMaskEqualMaster);
            sink.putLong(message.packetInMaskSlave);
            sink.putLong(message.portStatusMaskEqualMaster);
            sink.putLong(message.portStatusMaskSlave);
            sink.putLong(message.flowRemovedMaskEqualMaster);
            sink.putLong(message.flowRemovedMaskSlave);
        }
    }


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

    final static Writer WRITER = new Writer();
    static class Writer implements OFMessageWriter<OFAsyncGetReplyVer13> {
        @Override
        public void write(ChannelBuffer bb, OFAsyncGetReplyVer13 message) {
            // fixed value property version = 4
            bb.writeByte((byte) 0x4);
            // fixed value property type = 27
            bb.writeByte((byte) 0x1b);
            // fixed value property length = 32
            bb.writeShort((short) 0x20);
            bb.writeInt(U32.t(message.xid));
            bb.writeInt(U32.t(message.packetInMaskEqualMaster));
            bb.writeInt(U32.t(message.packetInMaskSlave));
            bb.writeInt(U32.t(message.portStatusMaskEqualMaster));
            bb.writeInt(U32.t(message.portStatusMaskSlave));
            bb.writeInt(U32.t(message.flowRemovedMaskEqualMaster));
            bb.writeInt(U32.t(message.flowRemovedMaskSlave));


        }
    }

    @Override
    public String toString() {
        StringBuilder b = new StringBuilder("OFAsyncGetReplyVer13(");
        b.append("xid=").append(xid);
        b.append(", ");
        b.append("packetInMaskEqualMaster=").append(packetInMaskEqualMaster);
        b.append(", ");
        b.append("packetInMaskSlave=").append(packetInMaskSlave);
        b.append(", ");
        b.append("portStatusMaskEqualMaster=").append(portStatusMaskEqualMaster);
        b.append(", ");
        b.append("portStatusMaskSlave=").append(portStatusMaskSlave);
        b.append(", ");
        b.append("flowRemovedMaskEqualMaster=").append(flowRemovedMaskEqualMaster);
        b.append(", ");
        b.append("flowRemovedMaskSlave=").append(flowRemovedMaskSlave);
        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;
        OFAsyncGetReplyVer13 other = (OFAsyncGetReplyVer13) obj;

        if( xid != other.xid)
            return false;
        if( packetInMaskEqualMaster != other.packetInMaskEqualMaster)
            return false;
        if( packetInMaskSlave != other.packetInMaskSlave)
            return false;
        if( portStatusMaskEqualMaster != other.portStatusMaskEqualMaster)
            return false;
        if( portStatusMaskSlave != other.portStatusMaskSlave)
            return false;
        if( flowRemovedMaskEqualMaster != other.flowRemovedMaskEqualMaster)
            return false;
        if( flowRemovedMaskSlave != other.flowRemovedMaskSlave)
            return false;
        return true;
    }

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

        result = prime *  (int) (xid ^ (xid >>> 32));
        result = prime *  (int) (packetInMaskEqualMaster ^ (packetInMaskEqualMaster >>> 32));
        result = prime *  (int) (packetInMaskSlave ^ (packetInMaskSlave >>> 32));
        result = prime *  (int) (portStatusMaskEqualMaster ^ (portStatusMaskEqualMaster >>> 32));
        result = prime *  (int) (portStatusMaskSlave ^ (portStatusMaskSlave >>> 32));
        result = prime *  (int) (flowRemovedMaskEqualMaster ^ (flowRemovedMaskEqualMaster >>> 32));
        result = prime *  (int) (flowRemovedMaskSlave ^ (flowRemovedMaskSlave >>> 32));
        return result;
    }

}
