package org.jboss.cache.commands.read;

import org.jboss.cache.Fqn;
import org.jboss.cache.InvocationContext;
import org.jboss.cache.NodeSPI;
import org.jboss.cache.commands.Visitor;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * This command retrieves the names of children for a specific Fqn, as defined by {@link org.jboss.cache.Node#getChildrenNames()}
 * <p/>
 * This is the equivalent of the old MethodCallDefinitions.getChildrenNamesMethodLocal method call from 2.1.x.
 * <p/>
 *
 * @author Mircea.Markus@jboss.com
 * @since 2.2.0
 */
public class GetChildrenNamesCommand extends AbstractDataCommand
{
   public static final int METHOD_ID = 23;

   public GetChildrenNamesCommand()
   {
   }

   public GetChildrenNamesCommand(Fqn fqn)
   {
      this.fqn = fqn;
   }

   /**
    * Retrieves the names of children for a specific Fqn.
    *
    * @param ctx invocation context
    * @return a Set<Object> of child names, for a given Fqn, or null if the Fqn refers to a node that does not exist.
    */
   public Object perform(InvocationContext ctx)
   {
      NodeSPI n = dataContainer.peek(fqn);
      if (n == null) return null;
      Map childrenMap = n.getChildrenMapDirect();
      if (childrenMap == null || childrenMap.isEmpty()) return Collections.emptySet();
      Set childNames = new HashSet();
      Collection s = childrenMap.values();
      // prune deleted children - JBCACHE-1136
      for (Object c : s)
      {
         NodeSPI child = (NodeSPI) c;
         if (!child.isDeleted())
         {
            Object e = child.getFqn().getLastElement();
            childNames.add(e);
         }
      }
      return childNames;
   }


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

   public int getCommandId()
   {
      return METHOD_ID;
   }
}
