// 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 OFBsnGentableStatsEntryVer13 implements OFBsnGentableStatsEntry {
    private static final Logger logger = LoggerFactory.getLogger(OFBsnGentableStatsEntryVer13.class);
    // version: 1.3
    final static byte WIRE_VERSION = 4;
    final static int LENGTH = 24;

        private final static long DEFAULT_ENTRY_COUNT = 0x0L;
        private final static U128 DEFAULT_CHECKSUM = U128.ZERO;

    // OF message fields
    private final GenTableId tableId;
    private final long entryCount;
    private final U128 checksum;
//

    // package private constructor - used by readers, builders, and factory
    OFBsnGentableStatsEntryVer13(GenTableId tableId, long entryCount, U128 checksum) {
        this.tableId = tableId;
        this.entryCount = entryCount;
        this.checksum = checksum;
    }

    // Accessors for OF message fields
    @Override
    public GenTableId getTableId() {
        return tableId;
    }

    @Override
    public long getEntryCount() {
        return entryCount;
    }

    @Override
    public U128 getChecksum() {
        return checksum;
    }

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



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

    static class BuilderWithParent implements OFBsnGentableStatsEntry.Builder {
        final OFBsnGentableStatsEntryVer13 parentMessage;

        // OF message fields
        private boolean tableIdSet;
        private GenTableId tableId;
        private boolean entryCountSet;
        private long entryCount;
        private boolean checksumSet;
        private U128 checksum;

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

    @Override
    public GenTableId getTableId() {
        return tableId;
    }

    @Override
    public OFBsnGentableStatsEntry.Builder setTableId(GenTableId tableId) {
        this.tableId = tableId;
        this.tableIdSet = true;
        return this;
    }
    @Override
    public long getEntryCount() {
        return entryCount;
    }

    @Override
    public OFBsnGentableStatsEntry.Builder setEntryCount(long entryCount) {
        this.entryCount = entryCount;
        this.entryCountSet = true;
        return this;
    }
    @Override
    public U128 getChecksum() {
        return checksum;
    }

    @Override
    public OFBsnGentableStatsEntry.Builder setChecksum(U128 checksum) {
        this.checksum = checksum;
        this.checksumSet = true;
        return this;
    }
    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_13;
    }



        @Override
        public OFBsnGentableStatsEntry build() {
                GenTableId tableId = this.tableIdSet ? this.tableId : parentMessage.tableId;
                if(tableId == null)
                    throw new NullPointerException("Property tableId must not be null");
                long entryCount = this.entryCountSet ? this.entryCount : parentMessage.entryCount;
                U128 checksum = this.checksumSet ? this.checksum : parentMessage.checksum;
                if(checksum == null)
                    throw new NullPointerException("Property checksum must not be null");

                //
                return new OFBsnGentableStatsEntryVer13(
                    tableId,
                    entryCount,
                    checksum
                );
        }

    }

    static class Builder implements OFBsnGentableStatsEntry.Builder {
        // OF message fields
        private boolean tableIdSet;
        private GenTableId tableId;
        private boolean entryCountSet;
        private long entryCount;
        private boolean checksumSet;
        private U128 checksum;

    @Override
    public GenTableId getTableId() {
        return tableId;
    }

    @Override
    public OFBsnGentableStatsEntry.Builder setTableId(GenTableId tableId) {
        this.tableId = tableId;
        this.tableIdSet = true;
        return this;
    }
    @Override
    public long getEntryCount() {
        return entryCount;
    }

    @Override
    public OFBsnGentableStatsEntry.Builder setEntryCount(long entryCount) {
        this.entryCount = entryCount;
        this.entryCountSet = true;
        return this;
    }
    @Override
    public U128 getChecksum() {
        return checksum;
    }

    @Override
    public OFBsnGentableStatsEntry.Builder setChecksum(U128 checksum) {
        this.checksum = checksum;
        this.checksumSet = true;
        return this;
    }
    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_13;
    }

//
        @Override
        public OFBsnGentableStatsEntry build() {
            if(!this.tableIdSet)
                throw new IllegalStateException("Property tableId doesn't have default value -- must be set");
            if(tableId == null)
                throw new NullPointerException("Property tableId must not be null");
            long entryCount = this.entryCountSet ? this.entryCount : DEFAULT_ENTRY_COUNT;
            U128 checksum = this.checksumSet ? this.checksum : DEFAULT_CHECKSUM;
            if(checksum == null)
                throw new NullPointerException("Property checksum must not be null");


            return new OFBsnGentableStatsEntryVer13(
                    tableId,
                    entryCount,
                    checksum
                );
        }

    }


    final static Reader READER = new Reader();
    static class Reader implements OFMessageReader<OFBsnGentableStatsEntry> {
        @Override
        public OFBsnGentableStatsEntry readFrom(ChannelBuffer bb) throws OFParseError {
            GenTableId tableId = GenTableId.read2Bytes(bb);
            // pad: 2 bytes
            bb.skipBytes(2);
            long entryCount = U32.f(bb.readInt());
            U128 checksum = U128.read16Bytes(bb);

            OFBsnGentableStatsEntryVer13 bsnGentableStatsEntryVer13 = new OFBsnGentableStatsEntryVer13(
                    tableId,
                      entryCount,
                      checksum
                    );
            if(logger.isTraceEnabled())
                logger.trace("readFrom - read={}", bsnGentableStatsEntryVer13);
            return bsnGentableStatsEntryVer13;
        }
    }

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

    final static OFBsnGentableStatsEntryVer13Funnel FUNNEL = new OFBsnGentableStatsEntryVer13Funnel();
    static class OFBsnGentableStatsEntryVer13Funnel implements Funnel<OFBsnGentableStatsEntryVer13> {
        private static final long serialVersionUID = 1L;
        @Override
        public void funnel(OFBsnGentableStatsEntryVer13 message, PrimitiveSink sink) {
            message.tableId.putTo(sink);
            // skip pad (2 bytes)
            sink.putLong(message.entryCount);
            message.checksum.putTo(sink);
        }
    }


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

    final static Writer WRITER = new Writer();
    static class Writer implements OFMessageWriter<OFBsnGentableStatsEntryVer13> {
        @Override
        public void write(ChannelBuffer bb, OFBsnGentableStatsEntryVer13 message) {
            message.tableId.write2Bytes(bb);
            // pad: 2 bytes
            bb.writeZero(2);
            bb.writeInt(U32.t(message.entryCount));
            message.checksum.write16Bytes(bb);


        }
    }

    @Override
    public String toString() {
        StringBuilder b = new StringBuilder("OFBsnGentableStatsEntryVer13(");
        b.append("tableId=").append(tableId);
        b.append(", ");
        b.append("entryCount=").append(entryCount);
        b.append(", ");
        b.append("checksum=").append(checksum);
        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;
        OFBsnGentableStatsEntryVer13 other = (OFBsnGentableStatsEntryVer13) obj;

        if (tableId == null) {
            if (other.tableId != null)
                return false;
        } else if (!tableId.equals(other.tableId))
            return false;
        if( entryCount != other.entryCount)
            return false;
        if (checksum == null) {
            if (other.checksum != null)
                return false;
        } else if (!checksum.equals(other.checksum))
            return false;
        return true;
    }

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

        result = prime * result + ((tableId == null) ? 0 : tableId.hashCode());
        result = prime *  (int) (entryCount ^ (entryCount >>> 32));
        result = prime * result + ((checksum == null) ? 0 : checksum.hashCode());
        return result;
    }

}
