package com.google.code.gossip.manager.impl;

import java.util.List;

import com.google.code.gossip.GossipMember;
import com.google.code.gossip.GossipService;
import com.google.code.gossip.LocalGossipMember;
import com.google.code.gossip.RemoteGossipMember;
import com.google.code.gossip.manager.GossipManager;
import com.google.code.gossip.manager.PassiveGossipThread;

public class OnlyProcessReceivedPassiveGossipThread extends PassiveGossipThread {

  public OnlyProcessReceivedPassiveGossipThread(GossipManager gossipManager) {
    super(gossipManager);
  }

  /**
   * Merge remote list (received from peer), and our local member list. Simply, we must update the
   * heartbeats that the remote list has with our list. Also, some additional logic is needed to
   * make sure we have not timed out a member and then immediately received a list with that member.
   * 
   * @param remoteList
   */
  protected void mergeLists(GossipManager gossipManager, RemoteGossipMember senderMember,
          List<GossipMember> remoteList) {

        for (GossipMember remoteMember : remoteList) {
          // Skip myself. We don't want ourselves in the local member list.
          if (remoteMember.equals(gossipManager.getMyself())) {
            continue;
          }
            if (gossipManager.getMemberList().contains(remoteMember)) {
              LocalGossipMember localMember = gossipManager.getMemberList().get(
                      gossipManager.getMemberList().indexOf(remoteMember));
              if (remoteMember.getHeartbeat() > localMember.getHeartbeat()) {
                localMember.setHeartbeat(remoteMember.getHeartbeat());
                localMember.resetTimeoutTimer();
              }
            } else {
              // The remote member is either brand new, or a previously declared dead member.
              // If its dead, check the heartbeat because it may have come back from the dead.
              if (gossipManager.getDeadList().contains(remoteMember)) {
                // The remote member is known here as a dead member.
                GossipService.LOGGER.debug("The remote member is known here as a dead member.");
                LocalGossipMember localDeadMember = gossipManager.getDeadList().get(
                        gossipManager.getDeadList().indexOf(remoteMember));
                // If a member is restarted the heartbeat will restart from 1, so we should check
                // that here.
                // So a member can become from the dead when it is either larger than a previous
                // heartbeat (due to network failure)
                // or when the heartbeat is 1 (after a restart of the service).
                // TODO: What if the first message of a gossip service is sent to a dead node? The
                // second member will receive a heartbeat of two.
                // TODO: The above does happen. Maybe a special message for a revived member?
                // TODO: Or maybe when a member is declared dead for more than
                // _settings.getCleanupInterval() ms, reset the heartbeat to 0.
                // It will then accept a revived member.
                // The above is now handle by checking whether the heartbeat differs
                // _settings.getCleanupInterval(), it must be restarted.
                if (remoteMember.getHeartbeat() == 1
                        || ((localDeadMember.getHeartbeat() - remoteMember.getHeartbeat()) * -1) > (gossipManager
                                .getSettings().getCleanupInterval() / 1000)
                        || remoteMember.getHeartbeat() > localDeadMember.getHeartbeat()) {
                  GossipService.LOGGER
                          .debug("The remote member is back from the dead. We will remove it from the dead list and add it as a new member.");
                  // The remote member is back from the dead.
                  // Remove it from the dead list.
                  //gossipManager.getDeadList().remove(localDeadMember);
                  // Add it as a new member and add it to the member list.
                  LocalGossipMember newLocalMember = new LocalGossipMember(remoteMember.getHost(),
                          remoteMember.getPort(), remoteMember.getId(),
                          remoteMember.getHeartbeat(), gossipManager, gossipManager.getSettings()
                                  .getCleanupInterval());
                  //gossipManager.getMemberList().add(newLocalMember);
                  gossipManager.createOrRevivieMember(newLocalMember);
                  newLocalMember.startTimeoutTimer();
                  GossipService.LOGGER.info("Removed remote member " + remoteMember.getAddress()
                          + " from dead list and added to local member list.");
                }
              } else {
                // Brand spanking new member - welcome.
                LocalGossipMember newLocalMember = new LocalGossipMember(remoteMember.getHost(),
                        remoteMember.getPort(), remoteMember.getId(), remoteMember.getHeartbeat(),
                        gossipManager, gossipManager.getSettings().getCleanupInterval());
                gossipManager.createOrRevivieMember(newLocalMember);
                newLocalMember.startTimeoutTimer();
                GossipService.LOGGER.info("Added new remote member " + remoteMember.getAddress()
                        + " to local member list.");
              }
            }
          }
        }

  

}
