package org.jboss.cache.commands.tx;

import org.jboss.cache.InvocationContext;
import org.jboss.cache.commands.ReversibleCommand;
import org.jboss.cache.commands.Visitor;
import org.jboss.cache.transaction.GlobalTransaction;
import org.jgroups.Address;

import java.util.List;
import java.util.Map;

/**
 * An optimistic version of {@link PrepareCommand}.
 *
 * @author Mircea.Markus@jboss.com
 * @since 2.2
 */
public class OptimisticPrepareCommand extends PrepareCommand
{
   public static final int METHOD_ID = 18;
   private Map data;

   public OptimisticPrepareCommand(GlobalTransaction gtx, List<ReversibleCommand> modifications, Map data, Address address, boolean onePhaseCommit)
   {
      super(gtx, modifications, address, onePhaseCommit);
      this.data = data;
   }

   public OptimisticPrepareCommand()
   {
   }

   @Override
   public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
   {
      return visitor.visitOptimisticPrepareCommand(ctx, this);
   }

   public Map getData()
   {
      return data;
   }

   @Override
   public int getCommandId()
   {
      return METHOD_ID;
   }

   @Override
   public Object[] getParameters()
   {
      return new Object[]{globalTransaction, modifications, data, localAddress, onePhaseCommit};
   }

   @Override
   public OptimisticPrepareCommand clone() throws CloneNotSupportedException
   {
      return (OptimisticPrepareCommand) super.clone();
   }

   @Override
   @SuppressWarnings("unchecked")
   public void setParameters(int commandId, Object[] args)
   {
      globalTransaction = (GlobalTransaction) args[0];
      modifications = (List<ReversibleCommand>) args[1];
      data = (Map) args[2];
      localAddress = (Address) args[3];
      onePhaseCommit = (Boolean) args[4];
   }

   @Override
   public boolean equals(Object o)
   {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
      if (!super.equals(o)) return false;

      OptimisticPrepareCommand that = (OptimisticPrepareCommand) o;

      if (data != null ? !data.equals(that.data) : that.data != null) return false;

      return true;
   }

   @Override
   public int hashCode()
   {
      int result = super.hashCode();
      result = 31 * result + (data != null ? data.hashCode() : 0);
      return result;
   }

   @Override
   public String toString()
   {
      return "OptimisticPrepareCommand{" +
            "data=" + data +
            "modifications=" + modifications +
            ", localAddress=" + localAddress +
            ", onePhaseCommit=" + onePhaseCommit +
            '}';
   }
}
