/*
 * 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.
 */
package org.apache.geode.internal.cache.tier.sockets;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

import org.apache.geode.DataSerializer;
import org.apache.geode.internal.cache.EnumListenerEvent;
import org.apache.geode.internal.cache.EventID;
import org.apache.geode.internal.cache.LocalRegion;
import org.apache.geode.internal.cache.tier.MessageType;
import org.apache.geode.internal.cache.versions.VersionSource;
import org.apache.geode.internal.serialization.DeserializationContext;
import org.apache.geode.internal.serialization.SerializationContext;
import org.apache.geode.internal.serialization.Version;

public class ClientTombstoneMessage extends ClientUpdateMessageImpl {

  enum TOperation {
    GC, GC_PR
  }

  private Object removalInformation;
  private TOperation op;

  /** GC operation for non-partitioned regions */
  public static ClientTombstoneMessage gc(LocalRegion region,
      Map<VersionSource, Long> regionGCVersions, EventID eventId) {
    return new ClientTombstoneMessage(TOperation.GC, region, regionGCVersions, eventId);
  }

  /** GC operation for partitioned regions */
  public static ClientTombstoneMessage gc(LocalRegion region, Set<Object> removedKeys,
      EventID eventId) {
    return new ClientTombstoneMessage(TOperation.GC_PR, region, removedKeys, eventId);
  }

  private ClientTombstoneMessage(TOperation op, LocalRegion region, Object removalInformation,
      EventID eventId) {
    super(EnumListenerEvent.AFTER_TOMBSTONE_EXPIRATION, null, eventId);
    this.op = op;
    this.removalInformation = removalInformation;
    setRegionName(region.getFullPath()); // fix for bug #45962 - tombstone message must have the
                                         // region name
  }

  /**
   * default constructor
   */
  public ClientTombstoneMessage() {}

  @Override
  public boolean shouldBeConflated() {
    return false;
  }

  /*
   * Returns a <code>Message</code> generated from the fields of this
   * <code>ClientTombstoneMessage</code>.
   */
  @Override
  protected Message getMessage(CacheClientProxy proxy, byte[] latestValue) throws IOException {
    if (Version.GFE_70.compareTo(proxy.getVersion()) <= 0) {
      return getGFE70Message(proxy.getVersion());
    } else {
      return null;
    }
  }

  protected Message getGFE70Message(Version clientVersion) {
    Message message = null;

    // The format:
    // part 0: operation (gc=0)
    // part 1: region name
    // part 2: operation ordinal
    // part 3: regionGCVersions
    // Last part: event ID
    int numParts = 4;
    message = new Message(numParts, clientVersion);
    // Set message type
    message.setMessageType(MessageType.TOMBSTONE_OPERATION);
    message.addStringPart(this.getRegionName(), true);
    message.addIntPart(this.op.ordinal());
    message.addObjPart(this.removalInformation);
    message.addObjPart(getEventId());
    return message;
  }

  @Override
  public int getDSFID() {
    return CLIENT_TOMBSTONE_MESSAGE;
  }

  @Override
  public void toData(DataOutput out,
      SerializationContext context) throws IOException {

    out.writeByte(op.ordinal());
    out.writeByte(_operation.getEventCode());
    DataSerializer.writeString(getRegionName(), out);
    DataSerializer.writeObject(this.removalInformation, out);
    DataSerializer.writeObject(this._membershipId, out);
    DataSerializer.writeObject(this._eventIdentifier, out);
  }

  @Override
  public void fromData(DataInput in,
      DeserializationContext context) throws IOException, ClassNotFoundException {
    // note: does not call super.fromData() since there are no keys, etc.
    // The message class hierarchy should be revised to have a more abstract
    // top-level class.
    this.op = TOperation.values()[in.readByte()];
    this._operation = EnumListenerEvent.getEnumListenerEvent(in.readByte());
    this.setRegionName(DataSerializer.readString(in));
    this.removalInformation = DataSerializer.readObject(in);
    this._membershipId = ClientProxyMembershipID.readCanonicalized(in);
    this._eventIdentifier = (EventID) DataSerializer.readObject(in);
  }

  @Override
  public Object getKeyToConflate() {
    return null;
  }

  @Override
  public String getRegionToConflate() {
    return null;
  }

  @Override
  public Object getValueToConflate() {
    return null;
  }

  @Override
  public void setLatestValue(Object value) {}

  @Override
  public boolean isClientInterested(ClientProxyMembershipID clientId) {
    return true;
  }

  @Override
  public boolean needsNoAuthorizationCheck() {
    return true;
  }

  @Override
  public String toString() {
    StringBuffer buffer = new StringBuffer();
    buffer.append("ClientTombstoneMessage[op=").append(this.op).append(";region=")
        .append(getRegionName()).append(";removalInfo=").append(this.removalInformation)
        .append(";memberId=").append(getMembershipId()).append(";eventId=").append(getEventId())
        .append("]");
    return buffer.toString();
  }
}
