/**
 * Autogenerated by Thrift Compiler (0.7.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 */
package net.floodlightcontroller.packetstreamer.thrift;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings("all") public class Packet implements org.apache.thrift.TBase<Packet, Packet._Fields>, java.io.Serializable, Cloneable {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Packet");

  private static final org.apache.thrift.protocol.TField MESSAGE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("messageType", org.apache.thrift.protocol.TType.I32, (short)1);
  private static final org.apache.thrift.protocol.TField SW_PORT_TUPLE_FIELD_DESC = new org.apache.thrift.protocol.TField("swPortTuple", org.apache.thrift.protocol.TType.STRUCT, (short)2);
  private static final org.apache.thrift.protocol.TField DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("data", org.apache.thrift.protocol.TType.STRING, (short)3);

  /**
   * 
   * @see OFMessageType
   */
  public OFMessageType messageType; // required
  public SwitchPortTuple swPortTuple; // required
  public ByteBuffer data; // required

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    /**
     * 
     * @see OFMessageType
     */
    MESSAGE_TYPE((short)1, "messageType"),
    SW_PORT_TUPLE((short)2, "swPortTuple"),
    DATA((short)3, "data");

    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

    static {
      for (_Fields field : EnumSet.allOf(_Fields.class)) {
        byName.put(field.getFieldName(), field);
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // MESSAGE_TYPE
          return MESSAGE_TYPE;
        case 2: // SW_PORT_TUPLE
          return SW_PORT_TUPLE;
        case 3: // DATA
          return DATA;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    public static _Fields findByName(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

    _Fields(short thriftId, String fieldName) {
      _thriftId = thriftId;
      _fieldName = fieldName;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments

  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.MESSAGE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("messageType", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, OFMessageType.class)));
    tmpMap.put(_Fields.SW_PORT_TUPLE, new org.apache.thrift.meta_data.FieldMetaData("swPortTuple", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SwitchPortTuple.class)));
    tmpMap.put(_Fields.DATA, new org.apache.thrift.meta_data.FieldMetaData("data", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Packet.class, metaDataMap);
  }

  public Packet() {
  }

  public Packet(
    OFMessageType messageType,
    SwitchPortTuple swPortTuple,
    ByteBuffer data)
  {
    this();
    this.messageType = messageType;
    this.swPortTuple = swPortTuple;
    this.data = data;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public Packet(Packet other) {
    if (other.isSetMessageType()) {
      this.messageType = other.messageType;
    }
    if (other.isSetSwPortTuple()) {
      this.swPortTuple = new SwitchPortTuple(other.swPortTuple);
    }
    if (other.isSetData()) {
      this.data = org.apache.thrift.TBaseHelper.copyBinary(other.data);
;
    }
  }

  public Packet deepCopy() {
    return new Packet(this);
  }

  @Override
  public void clear() {
    this.messageType = null;
    this.swPortTuple = null;
    this.data = null;
  }

  /**
   * 
   * @see OFMessageType
   */
  public OFMessageType getMessageType() {
    return this.messageType;
  }

  /**
   * 
   * @see OFMessageType
   */
  public Packet setMessageType(OFMessageType messageType) {
    this.messageType = messageType;
    return this;
  }

  public void unsetMessageType() {
    this.messageType = null;
  }

  /** Returns true if field messageType is set (has been assigned a value) and false otherwise */
  public boolean isSetMessageType() {
    return this.messageType != null;
  }

  public void setMessageTypeIsSet(boolean value) {
    if (!value) {
      this.messageType = null;
    }
  }

  public SwitchPortTuple getSwPortTuple() {
    return this.swPortTuple;
  }

  public Packet setSwPortTuple(SwitchPortTuple swPortTuple) {
    this.swPortTuple = swPortTuple;
    return this;
  }

  public void unsetSwPortTuple() {
    this.swPortTuple = null;
  }

  /** Returns true if field swPortTuple is set (has been assigned a value) and false otherwise */
  public boolean isSetSwPortTuple() {
    return this.swPortTuple != null;
  }

  public void setSwPortTupleIsSet(boolean value) {
    if (!value) {
      this.swPortTuple = null;
    }
  }

  public byte[] getData() {
    setData(org.apache.thrift.TBaseHelper.rightSize(data));
    return data == null ? null : data.array();
  }

  public ByteBuffer bufferForData() {
    return data;
  }

  public Packet setData(byte[] data) {
    setData(data == null ? (ByteBuffer)null : ByteBuffer.wrap(data));
    return this;
  }

  public Packet setData(ByteBuffer data) {
    this.data = data;
    return this;
  }

  public void unsetData() {
    this.data = null;
  }

  /** Returns true if field data is set (has been assigned a value) and false otherwise */
  public boolean isSetData() {
    return this.data != null;
  }

  public void setDataIsSet(boolean value) {
    if (!value) {
      this.data = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case MESSAGE_TYPE:
      if (value == null) {
        unsetMessageType();
      } else {
        setMessageType((OFMessageType)value);
      }
      break;

    case SW_PORT_TUPLE:
      if (value == null) {
        unsetSwPortTuple();
      } else {
        setSwPortTuple((SwitchPortTuple)value);
      }
      break;

    case DATA:
      if (value == null) {
        unsetData();
      } else {
        setData((ByteBuffer)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case MESSAGE_TYPE:
      return getMessageType();

    case SW_PORT_TUPLE:
      return getSwPortTuple();

    case DATA:
      return getData();

    }
    throw new IllegalStateException();
  }

  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new IllegalArgumentException();
    }

    switch (field) {
    case MESSAGE_TYPE:
      return isSetMessageType();
    case SW_PORT_TUPLE:
      return isSetSwPortTuple();
    case DATA:
      return isSetData();
    }
    throw new IllegalStateException();
  }

  @Override
  public boolean equals(Object that) {
    if (that == null)
      return false;
    if (that instanceof Packet)
      return this.equals((Packet)that);
    return false;
  }

  public boolean equals(Packet that) {
    if (that == null)
      return false;

    boolean this_present_messageType = true && this.isSetMessageType();
    boolean that_present_messageType = true && that.isSetMessageType();
    if (this_present_messageType || that_present_messageType) {
      if (!(this_present_messageType && that_present_messageType))
        return false;
      if (!this.messageType.equals(that.messageType))
        return false;
    }

    boolean this_present_swPortTuple = true && this.isSetSwPortTuple();
    boolean that_present_swPortTuple = true && that.isSetSwPortTuple();
    if (this_present_swPortTuple || that_present_swPortTuple) {
      if (!(this_present_swPortTuple && that_present_swPortTuple))
        return false;
      if (!this.swPortTuple.equals(that.swPortTuple))
        return false;
    }

    boolean this_present_data = true && this.isSetData();
    boolean that_present_data = true && that.isSetData();
    if (this_present_data || that_present_data) {
      if (!(this_present_data && that_present_data))
        return false;
      if (!this.data.equals(that.data))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    return 0;
  }

  public int compareTo(Packet other) {
    if (!getClass().equals(other.getClass())) {
      return getClass().getName().compareTo(other.getClass().getName());
    }

    int lastComparison = 0;
    Packet typedOther = (Packet)other;

    lastComparison = Boolean.valueOf(isSetMessageType()).compareTo(typedOther.isSetMessageType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetMessageType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.messageType, typedOther.messageType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetSwPortTuple()).compareTo(typedOther.isSetSwPortTuple());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetSwPortTuple()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.swPortTuple, typedOther.swPortTuple);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetData()).compareTo(typedOther.isSetData());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetData()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, typedOther.data);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    org.apache.thrift.protocol.TField field;
    iprot.readStructBegin();
    while (true)
    {
      field = iprot.readFieldBegin();
      if (field.type == org.apache.thrift.protocol.TType.STOP) { 
        break;
      }
      switch (field.id) {
        case 1: // MESSAGE_TYPE
          if (field.type == org.apache.thrift.protocol.TType.I32) {
            this.messageType = OFMessageType.findByValue(iprot.readI32());
          } else { 
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
          }
          break;
        case 2: // SW_PORT_TUPLE
          if (field.type == org.apache.thrift.protocol.TType.STRUCT) {
            this.swPortTuple = new SwitchPortTuple();
            this.swPortTuple.read(iprot);
          } else { 
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
          }
          break;
        case 3: // DATA
          if (field.type == org.apache.thrift.protocol.TType.STRING) {
            this.data = iprot.readBinary();
          } else { 
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
          }
          break;
        default:
          org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
      }
      iprot.readFieldEnd();
    }
    iprot.readStructEnd();

    // check for required fields of primitive type, which can't be checked in the validate method
    validate();
  }

  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    validate();

    oprot.writeStructBegin(STRUCT_DESC);
    if (this.messageType != null) {
      oprot.writeFieldBegin(MESSAGE_TYPE_FIELD_DESC);
      oprot.writeI32(this.messageType.getValue());
      oprot.writeFieldEnd();
    }
    if (this.swPortTuple != null) {
      oprot.writeFieldBegin(SW_PORT_TUPLE_FIELD_DESC);
      this.swPortTuple.write(oprot);
      oprot.writeFieldEnd();
    }
    if (this.data != null) {
      oprot.writeFieldBegin(DATA_FIELD_DESC);
      oprot.writeBinary(this.data);
      oprot.writeFieldEnd();
    }
    oprot.writeFieldStop();
    oprot.writeStructEnd();
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("Packet(");
    boolean first = true;

    sb.append("messageType:");
    if (this.messageType == null) {
      sb.append("null");
    } else {
      sb.append(this.messageType);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("swPortTuple:");
    if (this.swPortTuple == null) {
      sb.append("null");
    } else {
      sb.append(this.swPortTuple);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("data:");
    if (this.data == null) {
      sb.append("null");
    } else {
      org.apache.thrift.TBaseHelper.toString(this.data, sb);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
    try {
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

}

