/*
 * 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.persistence;

import static org.apache.geode.internal.cache.LocalRegion.InitializationLevel.ANY_INIT;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.logging.log4j.Logger;

import org.apache.geode.CancelException;
import org.apache.geode.DataSerializer;
import org.apache.geode.SystemFailure;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionDestroyedException;
import org.apache.geode.distributed.internal.ClusterDistributionManager;
import org.apache.geode.distributed.internal.DistributionManager;
import org.apache.geode.distributed.internal.DistributionMessage;
import org.apache.geode.distributed.internal.HighPriorityDistributionMessage;
import org.apache.geode.distributed.internal.MessageWithReply;
import org.apache.geode.distributed.internal.ReplyException;
import org.apache.geode.distributed.internal.ReplyMessage;
import org.apache.geode.distributed.internal.ReplyProcessor21;
import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import org.apache.geode.internal.cache.DistributedRegion;
import org.apache.geode.internal.cache.LocalRegion;
import org.apache.geode.internal.cache.LocalRegion.InitializationLevel;
import org.apache.geode.internal.cache.PartitionedRegionHelper;
import org.apache.geode.internal.cache.partitioned.Bucket;
import org.apache.geode.internal.serialization.DeserializationContext;
import org.apache.geode.internal.serialization.SerializationContext;
import org.apache.geode.logging.internal.log4j.api.LogService;

public class PersistentStateQueryMessage extends HighPriorityDistributionMessage
    implements MessageWithReply {

  private static final Logger logger = LogService.getLogger();

  private String regionPath;
  private PersistentMemberID id;
  private int processorId;
  private PersistentMemberID initializingId;

  public PersistentStateQueryMessage() {

  }

  public PersistentStateQueryMessage(String regionPath, PersistentMemberID id,
      PersistentMemberID initializingId, int processorId) {
    this.regionPath = regionPath;
    this.id = id;
    this.initializingId = initializingId;
    this.processorId = processorId;
  }

  PersistentStateQueryResults send(Set<InternalDistributedMember> members, DistributionManager dm,
      PersistentStateQueryReplyProcessor processor) {
    setRecipients(members);

    dm.putOutgoing(this);

    processor.waitForRepliesUninterruptibly();
    return processor.results;
  }

  @Override
  protected void process(ClusterDistributionManager dm) {
    final InitializationLevel oldLevel = LocalRegion.setThreadInitLevelRequirement(ANY_INIT);

    PersistentMemberState state = null;
    PersistentMemberID myId = null;
    PersistentMemberID myInitializingId = null;
    DiskStoreID diskStoreId = null;
    HashSet<PersistentMemberID> onlineMembers = null;
    ReplyException exception = null;
    boolean successfulReply = false;
    try {
      // get the region from the path, but do NOT wait on initialization,
      // otherwise we could have a distributed deadlock

      Cache cache = dm.getExistingCache();
      Region region = cache.getRegion(this.regionPath);
      PersistenceAdvisor persistenceAdvisor = null;
      if (region instanceof DistributedRegion) {
        persistenceAdvisor = ((DistributedRegion) region).getPersistenceAdvisor();
      } else if (region == null) {
        Bucket proxy =
            PartitionedRegionHelper.getProxyBucketRegion(dm.getCache(), this.regionPath, false);
        if (proxy != null) {
          persistenceAdvisor = proxy.getPersistenceAdvisor();
        }
      }
      if (persistenceAdvisor != null) {
        if (id != null) {
          state = persistenceAdvisor.getPersistedStateOfMember(id);
        }
        if (initializingId != null && state == null) {
          state = persistenceAdvisor.getPersistedStateOfMember(initializingId);
        }
        myId = persistenceAdvisor.getPersistentID();
        myInitializingId = persistenceAdvisor.getInitializingID();
        onlineMembers = persistenceAdvisor.getPersistedOnlineOrEqualMembers();
        diskStoreId = persistenceAdvisor.getDiskStoreID();
        successfulReply = true;
      }
    } catch (RegionDestroyedException e) {
      logger.debug("<RegionDestroyed> {}", this);
    } catch (CancelException e) {
      logger.debug("<CancelException> {}", this);
    } catch (VirtualMachineError e) {
      SystemFailure.initiateFailure(e);
      throw e;
    } catch (Throwable t) {
      SystemFailure.checkFailure();
      exception = new ReplyException(t);
    } finally {
      LocalRegion.setThreadInitLevelRequirement(oldLevel);
      ReplyMessage replyMsg;
      if (successfulReply) {
        PersistentStateQueryReplyMessage persistentReplyMessage =
            new PersistentStateQueryReplyMessage();
        persistentReplyMessage.myId = myId;
        persistentReplyMessage.persistedStateOfPeer = state;
        persistentReplyMessage.myInitializingId = myInitializingId;
        persistentReplyMessage.diskStoreId = diskStoreId;
        persistentReplyMessage.onlineMembers = onlineMembers;
        replyMsg = persistentReplyMessage;
      } else {
        replyMsg = new ReplyMessage();
      }
      replyMsg.setProcessorId(processorId);
      replyMsg.setRecipient(getSender());
      if (exception != null) {
        replyMsg.setException(exception);
      }
      if (logger.isDebugEnabled()) {
        logger.debug("Received {},replying with {}", this, replyMsg);
      }
      dm.putOutgoing(replyMsg);
    }
  }

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

  @Override
  public void fromData(DataInput in,
      DeserializationContext context) throws IOException, ClassNotFoundException {
    super.fromData(in, context);
    regionPath = DataSerializer.readString(in);
    processorId = in.readInt();
    boolean hasId = in.readBoolean();
    if (hasId) {
      id = new PersistentMemberID();
      id.fromData(in);
    }
    boolean hasInitializingId = in.readBoolean();
    if (hasInitializingId) {
      initializingId = new PersistentMemberID();
      initializingId.fromData(in);
    }
  }

  @Override
  public void toData(DataOutput out,
      SerializationContext context) throws IOException {
    super.toData(out, context);
    DataSerializer.writeString(regionPath, out);
    out.writeInt(processorId);
    out.writeBoolean(id != null);
    if (id != null) {
      id.toData(out);
    }
    out.writeBoolean(initializingId != null);
    if (initializingId != null) {
      initializingId.toData(out);
    }
  }

  @Override
  public String toString() {
    return super.toString() + ",id=" + id + ",regionPath=" + regionPath + ",initializingId="
        + initializingId;
  }

  static class PersistentStateQueryReplyProcessor extends ReplyProcessor21 {
    PersistentStateQueryResults results = new PersistentStateQueryResults();

    public PersistentStateQueryReplyProcessor(DistributionManager dm, Collection initMembers) {
      super(dm, initMembers);
    }

    @Override
    public void process(DistributionMessage msg) {
      if (msg instanceof PersistentStateQueryReplyMessage) {
        PersistentStateQueryReplyMessage reply = (PersistentStateQueryReplyMessage) msg;
        results.addResult(reply.persistedStateOfPeer, reply.getSender(), reply.myId,
            reply.myInitializingId, reply.diskStoreId, reply.onlineMembers);
      }
      super.process(msg);
    }
  }

  public static class PersistentStateQueryReplyMessage extends ReplyMessage {
    public HashSet<PersistentMemberID> onlineMembers;
    public DiskStoreID diskStoreId;
    private PersistentMemberState persistedStateOfPeer;
    private PersistentMemberID myId;
    private PersistentMemberID myInitializingId;

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

    @Override
    public void fromData(DataInput in,
        DeserializationContext context) throws IOException, ClassNotFoundException {
      super.fromData(in, context);
      boolean hasId = in.readBoolean();
      if (hasId) {
        myId = new PersistentMemberID();
        myId.fromData(in);
      }
      boolean hasState = in.readBoolean();
      if (hasState) {
        persistedStateOfPeer = PersistentMemberState.fromData(in);
      }
      boolean hasInitializingId = in.readBoolean();
      if (hasInitializingId) {
        myInitializingId = new PersistentMemberID();
        myInitializingId.fromData(in);
      }
      boolean hasDiskStoreID = in.readBoolean();
      if (hasDiskStoreID) {
        diskStoreId = new DiskStoreID(in.readLong(), in.readLong());
      }
      boolean hasOnlineMembers = in.readBoolean();
      if (hasOnlineMembers) {
        onlineMembers = DataSerializer.readHashSet(in);
      }
    }

    @Override
    public void toData(DataOutput out,
        SerializationContext context) throws IOException {
      super.toData(out, context);
      if (myId == null) {
        out.writeBoolean(false);
      } else {
        out.writeBoolean(true);
        myId.toData(out);
      }
      if (persistedStateOfPeer == null) {
        out.writeBoolean(false);
      } else {
        out.writeBoolean(true);
        persistedStateOfPeer.toData(out);
      }
      if (myInitializingId == null) {
        out.writeBoolean(false);
      } else {
        out.writeBoolean(true);
        myInitializingId.toData(out);
      }
      if (diskStoreId == null) {
        out.writeBoolean(false);
      } else {
        out.writeBoolean(true);
        out.writeLong(diskStoreId.getMostSignificantBits());
        out.writeLong(diskStoreId.getLeastSignificantBits());
      }
      if (onlineMembers == null) {
        out.writeBoolean(false);
      } else {
        out.writeBoolean(true);
        DataSerializer.writeHashSet(onlineMembers, out);
      }
    }

    @Override
    public String toString() {
      return super.toString() + ",myId=" + myId + ",myInitializingId=" + myInitializingId
          + ",persistedStateOfPeer=" + persistedStateOfPeer;
    }
  }
}
