/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Autogenerated by Thrift Compiler (0.18.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.model.tenant;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.18.1)")
public class TenantPreferences implements org.apache.thrift.TBase<TenantPreferences, TenantPreferences._Fields>, java.io.Serializable, Cloneable, Comparable<TenantPreferences> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TenantPreferences");

  private static final org.apache.thrift.protocol.TField TENANT_ADMIN_FIRST_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tenantAdminFirstName", org.apache.thrift.protocol.TType.STRING, (short)10);
  private static final org.apache.thrift.protocol.TField TENANT_ADMIN_LAST_NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("tenantAdminLastName", org.apache.thrift.protocol.TType.STRING, (short)11);
  private static final org.apache.thrift.protocol.TField TENANT_ADMIN_EMAIL_FIELD_DESC = new org.apache.thrift.protocol.TField("tenantAdminEmail", org.apache.thrift.protocol.TType.STRING, (short)12);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new TenantPreferencesStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new TenantPreferencesTupleSchemeFactory();

  private @org.apache.thrift.annotation.Nullable java.lang.String tenantAdminFirstName; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String tenantAdminLastName; // optional
  private @org.apache.thrift.annotation.Nullable java.lang.String tenantAdminEmail; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    TENANT_ADMIN_FIRST_NAME((short)10, "tenantAdminFirstName"),
    TENANT_ADMIN_LAST_NAME((short)11, "tenantAdminLastName"),
    TENANT_ADMIN_EMAIL((short)12, "tenantAdminEmail");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 10: // TENANT_ADMIN_FIRST_NAME
          return TENANT_ADMIN_FIRST_NAME;
        case 11: // TENANT_ADMIN_LAST_NAME
          return TENANT_ADMIN_LAST_NAME;
        case 12: // TENANT_ADMIN_EMAIL
          return TENANT_ADMIN_EMAIL;
        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 java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final java.lang.String _fieldName;

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

    @Override
    public short getThriftFieldId() {
      return _thriftId;
    }

    @Override
    public java.lang.String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final _Fields optionals[] = {_Fields.TENANT_ADMIN_FIRST_NAME,_Fields.TENANT_ADMIN_LAST_NAME,_Fields.TENANT_ADMIN_EMAIL};
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.TENANT_ADMIN_FIRST_NAME, new org.apache.thrift.meta_data.FieldMetaData("tenantAdminFirstName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TENANT_ADMIN_LAST_NAME, new org.apache.thrift.meta_data.FieldMetaData("tenantAdminLastName", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.TENANT_ADMIN_EMAIL, new org.apache.thrift.meta_data.FieldMetaData("tenantAdminEmail", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TenantPreferences.class, metaDataMap);
  }

  public TenantPreferences() {
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TenantPreferences(TenantPreferences other) {
    if (other.isSetTenantAdminFirstName()) {
      this.tenantAdminFirstName = other.tenantAdminFirstName;
    }
    if (other.isSetTenantAdminLastName()) {
      this.tenantAdminLastName = other.tenantAdminLastName;
    }
    if (other.isSetTenantAdminEmail()) {
      this.tenantAdminEmail = other.tenantAdminEmail;
    }
  }

  @Override
  public TenantPreferences deepCopy() {
    return new TenantPreferences(this);
  }

  @Override
  public void clear() {
    this.tenantAdminFirstName = null;
    this.tenantAdminLastName = null;
    this.tenantAdminEmail = null;
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getTenantAdminFirstName() {
    return this.tenantAdminFirstName;
  }

  public void setTenantAdminFirstName(@org.apache.thrift.annotation.Nullable java.lang.String tenantAdminFirstName) {
    this.tenantAdminFirstName = tenantAdminFirstName;
  }

  public void unsetTenantAdminFirstName() {
    this.tenantAdminFirstName = null;
  }

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

  public void setTenantAdminFirstNameIsSet(boolean value) {
    if (!value) {
      this.tenantAdminFirstName = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getTenantAdminLastName() {
    return this.tenantAdminLastName;
  }

  public void setTenantAdminLastName(@org.apache.thrift.annotation.Nullable java.lang.String tenantAdminLastName) {
    this.tenantAdminLastName = tenantAdminLastName;
  }

  public void unsetTenantAdminLastName() {
    this.tenantAdminLastName = null;
  }

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

  public void setTenantAdminLastNameIsSet(boolean value) {
    if (!value) {
      this.tenantAdminLastName = null;
    }
  }

  @org.apache.thrift.annotation.Nullable
  public java.lang.String getTenantAdminEmail() {
    return this.tenantAdminEmail;
  }

  public void setTenantAdminEmail(@org.apache.thrift.annotation.Nullable java.lang.String tenantAdminEmail) {
    this.tenantAdminEmail = tenantAdminEmail;
  }

  public void unsetTenantAdminEmail() {
    this.tenantAdminEmail = null;
  }

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

  public void setTenantAdminEmailIsSet(boolean value) {
    if (!value) {
      this.tenantAdminEmail = null;
    }
  }

  @Override
  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case TENANT_ADMIN_FIRST_NAME:
      if (value == null) {
        unsetTenantAdminFirstName();
      } else {
        setTenantAdminFirstName((java.lang.String)value);
      }
      break;

    case TENANT_ADMIN_LAST_NAME:
      if (value == null) {
        unsetTenantAdminLastName();
      } else {
        setTenantAdminLastName((java.lang.String)value);
      }
      break;

    case TENANT_ADMIN_EMAIL:
      if (value == null) {
        unsetTenantAdminEmail();
      } else {
        setTenantAdminEmail((java.lang.String)value);
      }
      break;

    }
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case TENANT_ADMIN_FIRST_NAME:
      return getTenantAdminFirstName();

    case TENANT_ADMIN_LAST_NAME:
      return getTenantAdminLastName();

    case TENANT_ADMIN_EMAIL:
      return getTenantAdminEmail();

    }
    throw new java.lang.IllegalStateException();
  }

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

    switch (field) {
    case TENANT_ADMIN_FIRST_NAME:
      return isSetTenantAdminFirstName();
    case TENANT_ADMIN_LAST_NAME:
      return isSetTenantAdminLastName();
    case TENANT_ADMIN_EMAIL:
      return isSetTenantAdminEmail();
    }
    throw new java.lang.IllegalStateException();
  }

  @Override
  public boolean equals(java.lang.Object that) {
    if (that instanceof TenantPreferences)
      return this.equals((TenantPreferences)that);
    return false;
  }

  public boolean equals(TenantPreferences that) {
    if (that == null)
      return false;
    if (this == that)
      return true;

    boolean this_present_tenantAdminFirstName = true && this.isSetTenantAdminFirstName();
    boolean that_present_tenantAdminFirstName = true && that.isSetTenantAdminFirstName();
    if (this_present_tenantAdminFirstName || that_present_tenantAdminFirstName) {
      if (!(this_present_tenantAdminFirstName && that_present_tenantAdminFirstName))
        return false;
      if (!this.tenantAdminFirstName.equals(that.tenantAdminFirstName))
        return false;
    }

    boolean this_present_tenantAdminLastName = true && this.isSetTenantAdminLastName();
    boolean that_present_tenantAdminLastName = true && that.isSetTenantAdminLastName();
    if (this_present_tenantAdminLastName || that_present_tenantAdminLastName) {
      if (!(this_present_tenantAdminLastName && that_present_tenantAdminLastName))
        return false;
      if (!this.tenantAdminLastName.equals(that.tenantAdminLastName))
        return false;
    }

    boolean this_present_tenantAdminEmail = true && this.isSetTenantAdminEmail();
    boolean that_present_tenantAdminEmail = true && that.isSetTenantAdminEmail();
    if (this_present_tenantAdminEmail || that_present_tenantAdminEmail) {
      if (!(this_present_tenantAdminEmail && that_present_tenantAdminEmail))
        return false;
      if (!this.tenantAdminEmail.equals(that.tenantAdminEmail))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 8191 + ((isSetTenantAdminFirstName()) ? 131071 : 524287);
    if (isSetTenantAdminFirstName())
      hashCode = hashCode * 8191 + tenantAdminFirstName.hashCode();

    hashCode = hashCode * 8191 + ((isSetTenantAdminLastName()) ? 131071 : 524287);
    if (isSetTenantAdminLastName())
      hashCode = hashCode * 8191 + tenantAdminLastName.hashCode();

    hashCode = hashCode * 8191 + ((isSetTenantAdminEmail()) ? 131071 : 524287);
    if (isSetTenantAdminEmail())
      hashCode = hashCode * 8191 + tenantAdminEmail.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(isSetTenantAdminFirstName(), other.isSetTenantAdminFirstName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTenantAdminFirstName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tenantAdminFirstName, other.tenantAdminFirstName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTenantAdminLastName(), other.isSetTenantAdminLastName());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTenantAdminLastName()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tenantAdminLastName, other.tenantAdminLastName);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetTenantAdminEmail(), other.isSetTenantAdminEmail());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetTenantAdminEmail()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.tenantAdminEmail, other.tenantAdminEmail);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  @Override
  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    scheme(iprot).read(iprot, this);
  }

  @Override
  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    scheme(oprot).write(oprot, this);
  }

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("TenantPreferences(");
    boolean first = true;

    if (isSetTenantAdminFirstName()) {
      sb.append("tenantAdminFirstName:");
      if (this.tenantAdminFirstName == null) {
        sb.append("null");
      } else {
        sb.append(this.tenantAdminFirstName);
      }
      first = false;
    }
    if (isSetTenantAdminLastName()) {
      if (!first) sb.append(", ");
      sb.append("tenantAdminLastName:");
      if (this.tenantAdminLastName == null) {
        sb.append("null");
      } else {
        sb.append(this.tenantAdminLastName);
      }
      first = false;
    }
    if (isSetTenantAdminEmail()) {
      if (!first) sb.append(", ");
      sb.append("tenantAdminEmail:");
      if (this.tenantAdminEmail == null) {
        sb.append("null");
      } else {
        sb.append(this.tenantAdminEmail);
      }
      first = false;
    }
    sb.append(")");
    return sb.toString();
  }

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

  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, java.lang.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);
    }
  }

  private static class TenantPreferencesStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public TenantPreferencesStandardScheme getScheme() {
      return new TenantPreferencesStandardScheme();
    }
  }

  private static class TenantPreferencesStandardScheme extends org.apache.thrift.scheme.StandardScheme<TenantPreferences> {

    @Override
    public void read(org.apache.thrift.protocol.TProtocol iprot, TenantPreferences struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 10: // TENANT_ADMIN_FIRST_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.tenantAdminFirstName = iprot.readString();
              struct.setTenantAdminFirstNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 11: // TENANT_ADMIN_LAST_NAME
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.tenantAdminLastName = iprot.readString();
              struct.setTenantAdminLastNameIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 12: // TENANT_ADMIN_EMAIL
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.tenantAdminEmail = iprot.readString();
              struct.setTenantAdminEmailIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();
      struct.validate();
    }

    @Override
    public void write(org.apache.thrift.protocol.TProtocol oprot, TenantPreferences struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.tenantAdminFirstName != null) {
        if (struct.isSetTenantAdminFirstName()) {
          oprot.writeFieldBegin(TENANT_ADMIN_FIRST_NAME_FIELD_DESC);
          oprot.writeString(struct.tenantAdminFirstName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.tenantAdminLastName != null) {
        if (struct.isSetTenantAdminLastName()) {
          oprot.writeFieldBegin(TENANT_ADMIN_LAST_NAME_FIELD_DESC);
          oprot.writeString(struct.tenantAdminLastName);
          oprot.writeFieldEnd();
        }
      }
      if (struct.tenantAdminEmail != null) {
        if (struct.isSetTenantAdminEmail()) {
          oprot.writeFieldBegin(TENANT_ADMIN_EMAIL_FIELD_DESC);
          oprot.writeString(struct.tenantAdminEmail);
          oprot.writeFieldEnd();
        }
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TenantPreferencesTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public TenantPreferencesTupleScheme getScheme() {
      return new TenantPreferencesTupleScheme();
    }
  }

  private static class TenantPreferencesTupleScheme extends org.apache.thrift.scheme.TupleScheme<TenantPreferences> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, TenantPreferences struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet optionals = new java.util.BitSet();
      if (struct.isSetTenantAdminFirstName()) {
        optionals.set(0);
      }
      if (struct.isSetTenantAdminLastName()) {
        optionals.set(1);
      }
      if (struct.isSetTenantAdminEmail()) {
        optionals.set(2);
      }
      oprot.writeBitSet(optionals, 3);
      if (struct.isSetTenantAdminFirstName()) {
        oprot.writeString(struct.tenantAdminFirstName);
      }
      if (struct.isSetTenantAdminLastName()) {
        oprot.writeString(struct.tenantAdminLastName);
      }
      if (struct.isSetTenantAdminEmail()) {
        oprot.writeString(struct.tenantAdminEmail);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, TenantPreferences struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      java.util.BitSet incoming = iprot.readBitSet(3);
      if (incoming.get(0)) {
        struct.tenantAdminFirstName = iprot.readString();
        struct.setTenantAdminFirstNameIsSet(true);
      }
      if (incoming.get(1)) {
        struct.tenantAdminLastName = iprot.readString();
        struct.setTenantAdminLastNameIsSet(true);
      }
      if (incoming.get(2)) {
        struct.tenantAdminEmail = iprot.readString();
        struct.setTenantAdminEmailIsSet(true);
      }
    }
  }

  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

