/*
 * Copyright 2011 Google Inc.
 *
 * Licensed 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.
 */
// Generated by j/c/g/ipc/invalidation/common/proto_wrapper_generator
package com.google.ipc.invalidation.ticl.proto;

import com.google.ipc.invalidation.util.Bytes;
import com.google.ipc.invalidation.util.ProtoWrapper;
import com.google.ipc.invalidation.util.ProtoWrapper.ValidationException;
import com.google.ipc.invalidation.util.TextBuilder;
import com.google.protobuf.nano.MessageNano;
import com.google.protobuf.nano.InvalidProtocolBufferNanoException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


public interface Client {

  public static final class AckHandleP extends ProtoWrapper {
    public static AckHandleP create(com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP invalidation) {
      return new AckHandleP(invalidation);
    }

    public static final AckHandleP DEFAULT_INSTANCE = new AckHandleP(null);

    private final com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP invalidation;

    private AckHandleP(com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP invalidation) {
      this.invalidation = invalidation;
    }

    public com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP getNullableInvalidation() { return invalidation; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof AckHandleP)) { return false; }
      AckHandleP other = (AckHandleP) obj;
      return equals(invalidation, other.invalidation);
    }

    @Override protected int computeHashCode() {
      int result = 1;
      if (invalidation != null) {
        result = result * 31 + invalidation.hashCode();
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<AckHandleP:");
      if (invalidation != null) {
        builder.append(" invalidation=").append(invalidation);
      }
      builder.append('>');
    }

    public static AckHandleP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.NanoClient.AckHandleP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static AckHandleP fromMessageNano(com.google.protos.ipc.invalidation.NanoClient.AckHandleP message) {
      if (message == null) { return null; }
      return new AckHandleP(com.google.ipc.invalidation.ticl.proto.ClientProtocol.InvalidationP.fromMessageNano(message.invalidation));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.NanoClient.AckHandleP toMessageNano() {
      com.google.protos.ipc.invalidation.NanoClient.AckHandleP msg = new com.google.protos.ipc.invalidation.NanoClient.AckHandleP();
      msg.invalidation = this.invalidation != null ? invalidation.toMessageNano() : null;
      return msg;
    }
  }

  public static final class PersistentTiclState extends ProtoWrapper {
    public static final class Builder {
      public Bytes clientToken;
      public Long lastMessageSendTimeMs;
      public Builder() {
      }

      public PersistentTiclState build() {
        return new PersistentTiclState(clientToken, lastMessageSendTimeMs);
      }
    }

    public static PersistentTiclState create(Bytes clientToken,
        Long lastMessageSendTimeMs) {
      return new PersistentTiclState(clientToken, lastMessageSendTimeMs);
    }

    public static final PersistentTiclState DEFAULT_INSTANCE = new PersistentTiclState(null, null);

    private final long __hazzerBits;
    private final Bytes clientToken;
    private final long lastMessageSendTimeMs;

    private PersistentTiclState(Bytes clientToken,
        Long lastMessageSendTimeMs) {
      int hazzerBits = 0;
      if (clientToken != null) {
        hazzerBits |= 0x1;
        this.clientToken = clientToken;
      } else {
        this.clientToken = Bytes.EMPTY_BYTES;
      }
      if (lastMessageSendTimeMs != null) {
        hazzerBits |= 0x2;
        this.lastMessageSendTimeMs = lastMessageSendTimeMs;
      } else {
        this.lastMessageSendTimeMs = 0;
      }
      this.__hazzerBits = hazzerBits;
    }

    public Bytes getClientToken() { return clientToken; }
    public boolean hasClientToken() { return (0x1 & __hazzerBits) != 0; }

    public long getLastMessageSendTimeMs() { return lastMessageSendTimeMs; }
    public boolean hasLastMessageSendTimeMs() { return (0x2 & __hazzerBits) != 0; }

    public Builder toBuilder() {
      Builder builder = new Builder();
      if (hasClientToken()) {
        builder.clientToken = clientToken;
      }
      if (hasLastMessageSendTimeMs()) {
        builder.lastMessageSendTimeMs = lastMessageSendTimeMs;
      }
      return builder;
    }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof PersistentTiclState)) { return false; }
      PersistentTiclState other = (PersistentTiclState) obj;
      return __hazzerBits == other.__hazzerBits
          && (!hasClientToken() || equals(clientToken, other.clientToken))
          && (!hasLastMessageSendTimeMs() || lastMessageSendTimeMs == other.lastMessageSendTimeMs);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (hasClientToken()) {
        result = result * 31 + clientToken.hashCode();
      }
      if (hasLastMessageSendTimeMs()) {
        result = result * 31 + hash(lastMessageSendTimeMs);
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<PersistentTiclState:");
      if (hasClientToken()) {
        builder.append(" client_token=").append(clientToken);
      }
      if (hasLastMessageSendTimeMs()) {
        builder.append(" last_message_send_time_ms=").append(lastMessageSendTimeMs);
      }
      builder.append('>');
    }

    public static PersistentTiclState parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.NanoClient.PersistentTiclState(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static PersistentTiclState fromMessageNano(com.google.protos.ipc.invalidation.NanoClient.PersistentTiclState message) {
      if (message == null) { return null; }
      return new PersistentTiclState(Bytes.fromByteArray(message.clientToken),
          message.lastMessageSendTimeMs);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.NanoClient.PersistentTiclState toMessageNano() {
      com.google.protos.ipc.invalidation.NanoClient.PersistentTiclState msg = new com.google.protos.ipc.invalidation.NanoClient.PersistentTiclState();
      msg.clientToken = hasClientToken() ? clientToken.getByteArray() : null;
      msg.lastMessageSendTimeMs = hasLastMessageSendTimeMs() ? lastMessageSendTimeMs : null;
      return msg;
    }
  }

  public static final class PersistentStateBlob extends ProtoWrapper {
    public static PersistentStateBlob create(com.google.ipc.invalidation.ticl.proto.Client.PersistentTiclState ticlState,
        Bytes authenticationCode) {
      return new PersistentStateBlob(ticlState, authenticationCode);
    }

    public static final PersistentStateBlob DEFAULT_INSTANCE = new PersistentStateBlob(null, null);

    private final long __hazzerBits;
    private final com.google.ipc.invalidation.ticl.proto.Client.PersistentTiclState ticlState;
    private final Bytes authenticationCode;

    private PersistentStateBlob(com.google.ipc.invalidation.ticl.proto.Client.PersistentTiclState ticlState,
        Bytes authenticationCode) {
      int hazzerBits = 0;
      if (ticlState != null) {
        hazzerBits |= 0x1;
        this.ticlState = ticlState;
      } else {
        this.ticlState = com.google.ipc.invalidation.ticl.proto.Client.PersistentTiclState.DEFAULT_INSTANCE;
      }
      if (authenticationCode != null) {
        hazzerBits |= 0x2;
        this.authenticationCode = authenticationCode;
      } else {
        this.authenticationCode = Bytes.EMPTY_BYTES;
      }
      this.__hazzerBits = hazzerBits;
    }

    public com.google.ipc.invalidation.ticl.proto.Client.PersistentTiclState getTiclState() { return ticlState; }
    public boolean hasTiclState() { return (0x1 & __hazzerBits) != 0; }

    public Bytes getAuthenticationCode() { return authenticationCode; }
    public boolean hasAuthenticationCode() { return (0x2 & __hazzerBits) != 0; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof PersistentStateBlob)) { return false; }
      PersistentStateBlob other = (PersistentStateBlob) obj;
      return __hazzerBits == other.__hazzerBits
          && (!hasTiclState() || equals(ticlState, other.ticlState))
          && (!hasAuthenticationCode() || equals(authenticationCode, other.authenticationCode));
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (hasTiclState()) {
        result = result * 31 + ticlState.hashCode();
      }
      if (hasAuthenticationCode()) {
        result = result * 31 + authenticationCode.hashCode();
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<PersistentStateBlob:");
      if (hasTiclState()) {
        builder.append(" ticl_state=").append(ticlState);
      }
      if (hasAuthenticationCode()) {
        builder.append(" authentication_code=").append(authenticationCode);
      }
      builder.append('>');
    }

    public static PersistentStateBlob parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.NanoClient.PersistentStateBlob(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static PersistentStateBlob fromMessageNano(com.google.protos.ipc.invalidation.NanoClient.PersistentStateBlob message) {
      if (message == null) { return null; }
      return new PersistentStateBlob(com.google.ipc.invalidation.ticl.proto.Client.PersistentTiclState.fromMessageNano(message.ticlState),
          Bytes.fromByteArray(message.authenticationCode));
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.NanoClient.PersistentStateBlob toMessageNano() {
      com.google.protos.ipc.invalidation.NanoClient.PersistentStateBlob msg = new com.google.protos.ipc.invalidation.NanoClient.PersistentStateBlob();
      msg.ticlState = hasTiclState() ? ticlState.toMessageNano() : null;
      msg.authenticationCode = hasAuthenticationCode() ? authenticationCode.getByteArray() : null;
      return msg;
    }
  }

  public static final class RunStateP extends ProtoWrapper {
    public interface State {
      public static final int NOT_STARTED = 1;
      public static final int STARTED = 2;
      public static final int STOPPED = 3;
    }

    public static RunStateP create(Integer state) {
      return new RunStateP(state);
    }

    public static final RunStateP DEFAULT_INSTANCE = new RunStateP(null);

    private final long __hazzerBits;
    private final int state;

    private RunStateP(Integer state) {
      int hazzerBits = 0;
      if (state != null) {
        hazzerBits |= 0x1;
        this.state = state;
      } else {
        this.state = 1;
      }
      this.__hazzerBits = hazzerBits;
    }

    public int getState() { return state; }
    public boolean hasState() { return (0x1 & __hazzerBits) != 0; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof RunStateP)) { return false; }
      RunStateP other = (RunStateP) obj;
      return __hazzerBits == other.__hazzerBits
          && (!hasState() || state == other.state);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (hasState()) {
        result = result * 31 + hash(state);
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<RunStateP:");
      if (hasState()) {
        builder.append(" state=").append(state);
      }
      builder.append('>');
    }

    public static RunStateP parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.NanoClient.RunStateP(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static RunStateP fromMessageNano(com.google.protos.ipc.invalidation.NanoClient.RunStateP message) {
      if (message == null) { return null; }
      return new RunStateP(message.state);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.NanoClient.RunStateP toMessageNano() {
      com.google.protos.ipc.invalidation.NanoClient.RunStateP msg = new com.google.protos.ipc.invalidation.NanoClient.RunStateP();
      msg.state = hasState() ? state : null;
      return msg;
    }
  }

  public static final class ExponentialBackoffState extends ProtoWrapper {
    public static ExponentialBackoffState create(Integer currentMaxDelay,
        Boolean inRetryMode) {
      return new ExponentialBackoffState(currentMaxDelay, inRetryMode);
    }

    public static final ExponentialBackoffState DEFAULT_INSTANCE = new ExponentialBackoffState(null, null);

    private final long __hazzerBits;
    private final int currentMaxDelay;
    private final boolean inRetryMode;

    private ExponentialBackoffState(Integer currentMaxDelay,
        Boolean inRetryMode) {
      int hazzerBits = 0;
      if (currentMaxDelay != null) {
        hazzerBits |= 0x1;
        this.currentMaxDelay = currentMaxDelay;
      } else {
        this.currentMaxDelay = 0;
      }
      if (inRetryMode != null) {
        hazzerBits |= 0x2;
        this.inRetryMode = inRetryMode;
      } else {
        this.inRetryMode = false;
      }
      this.__hazzerBits = hazzerBits;
    }

    public int getCurrentMaxDelay() { return currentMaxDelay; }
    public boolean hasCurrentMaxDelay() { return (0x1 & __hazzerBits) != 0; }

    public boolean getInRetryMode() { return inRetryMode; }
    public boolean hasInRetryMode() { return (0x2 & __hazzerBits) != 0; }

    @Override public final boolean equals(Object obj) {
      if (this == obj) { return true; }
      if (!(obj instanceof ExponentialBackoffState)) { return false; }
      ExponentialBackoffState other = (ExponentialBackoffState) obj;
      return __hazzerBits == other.__hazzerBits
          && (!hasCurrentMaxDelay() || currentMaxDelay == other.currentMaxDelay)
          && (!hasInRetryMode() || inRetryMode == other.inRetryMode);
    }

    @Override protected int computeHashCode() {
      int result = hash(__hazzerBits);
      if (hasCurrentMaxDelay()) {
        result = result * 31 + hash(currentMaxDelay);
      }
      if (hasInRetryMode()) {
        result = result * 31 + hash(inRetryMode);
      }
      return result;
    }

    @Override public void toCompactString(TextBuilder builder) {
      builder.append("<ExponentialBackoffState:");
      if (hasCurrentMaxDelay()) {
        builder.append(" current_max_delay=").append(currentMaxDelay);
      }
      if (hasInRetryMode()) {
        builder.append(" in_retry_mode=").append(inRetryMode);
      }
      builder.append('>');
    }

    public static ExponentialBackoffState parseFrom(byte[] data) throws ValidationException {
      try {
        return fromMessageNano(MessageNano.mergeFrom(new com.google.protos.ipc.invalidation.NanoClient.ExponentialBackoffState(), data));
      } catch (InvalidProtocolBufferNanoException exception) {
        throw new ValidationException(exception);
      } catch (ValidationArgumentException exception) {
        throw new ValidationException(exception.getMessage());
      }
    }

    static ExponentialBackoffState fromMessageNano(com.google.protos.ipc.invalidation.NanoClient.ExponentialBackoffState message) {
      if (message == null) { return null; }
      return new ExponentialBackoffState(message.currentMaxDelay,
          message.inRetryMode);
    }

    public byte[] toByteArray() {
      return MessageNano.toByteArray(toMessageNano());
    }

    com.google.protos.ipc.invalidation.NanoClient.ExponentialBackoffState toMessageNano() {
      com.google.protos.ipc.invalidation.NanoClient.ExponentialBackoffState msg = new com.google.protos.ipc.invalidation.NanoClient.ExponentialBackoffState();
      msg.currentMaxDelay = hasCurrentMaxDelay() ? currentMaxDelay : null;
      msg.inRetryMode = hasInRetryMode() ? inRetryMode : null;
      return msg;
    }
  }
}
