/**
 * Copyright 2013 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Eclipse Public License version 1.0, available at
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.jboss.forge.addon.shell.aesh;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jboss.aesh.console.command.Command;
import org.jboss.aesh.console.command.CommandResult;
import org.jboss.aesh.console.command.invocation.CommandInvocation;
import org.jboss.forge.addon.resource.Resource;
import org.jboss.forge.addon.shell.ShellImpl;
import org.jboss.forge.addon.shell.ShellMessages;
import org.jboss.forge.addon.shell.ui.ShellContext;
import org.jboss.forge.addon.ui.output.UIMessage;
import org.jboss.forge.addon.ui.output.UIMessage.Severity;
import org.jboss.forge.addon.ui.result.CompositeResult;
import org.jboss.forge.addon.ui.result.Failed;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.addon.ui.result.Results;
import org.jboss.forge.furnace.util.Strings;

/**
 * Adapts the current {@link AbstractShellInteraction} to a {@link Command}
 * 
 * @author <a href="ggastald@redhat.com">George Gastaldi</a>
 * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
 */
class CommandAdapter implements Command<CommandInvocation>
{
   private static final Logger log = Logger.getLogger(CommandAdapter.class.getName());

   private final ShellImpl shell;
   private final ShellContext shellContext;
   private final AbstractShellInteraction interaction;

   public CommandAdapter(ShellImpl shell, ShellContext shellContext, AbstractShellInteraction interaction)
   {
      this.shell = shell;
      this.shellContext = shellContext;
      this.interaction = interaction;
   }

   public List<UIMessage> validate()
   {
      return interaction.getController().validate();
   }

   @SuppressWarnings("unchecked")
   @Override
   public CommandResult execute(CommandInvocation commandInvocation) throws IOException
   {
      Map<Object, Object> attributeMap = shellContext.getAttributeMap();
      attributeMap.put(CommandInvocation.class, commandInvocation);
      boolean failure = false;
      // FORGE-1668: Prompt for required missing values
      if (shellContext.isInteractive())
      {
         interaction.promptRequiredMissingValues(shell);
      }
      if (interaction.getController().isValid())
      {
         Result commandResult = null;
         try
         {
            commandResult = interaction.getController().execute();
         }
         catch (Exception e)
         {
            log.log(Level.SEVERE, "Failed to execute [" + interaction.getName() + "] due to exception.", e);
            commandResult = Results.fail(e.getMessage(), e);
         }
         failure = displayResult(commandResult);
         Object selection = interaction.getContext().getSelection();
         if (selection != null)
         {
            if (selection instanceof Iterable<?>)
            {
               for (Resource<?> item : (Iterable<Resource<?>>) selection)
               {
                  if (item != null)
                  {
                     shell.setCurrentResource(item);
                     break;
                  }
               }
            }
            else
            {
               shell.setCurrentResource((Resource<?>) selection);
            }
         }
      }
      else
      {
         List<UIMessage> messages = interaction.getController().validate();
         for (UIMessage message : messages)
         {
            if (message.getSeverity() == Severity.ERROR)
            {
               failure = true;
               ShellMessages.error(shell.getConsole().getShell().err(), message.getDescription());
            }
         }
      }
      return failure ? CommandResult.FAILURE : CommandResult.SUCCESS;
   }

   private boolean displayResult(Result result)
   {
      boolean failure = false;
      if (result instanceof CompositeResult)
      {
         for (Result thisResult : ((CompositeResult) result).getResults())
         {
            if (!displayResult(thisResult))
            {
               failure = true;
            }
         }
      }
      else if (result != null && !Strings.isNullOrEmpty(result.getMessage()))
      {
         if (result instanceof Failed)
         {
            ShellMessages.error(shell.getConsole().getShell().err(), result.getMessage());
            log.log(Level.SEVERE, result.getMessage(), ((Failed) result).getException());
            failure = true;
         }
         else
         {
            ShellMessages.success(shell.getConsole().getShell().out(), result.getMessage());
            failure = false;
         }
      }
      return failure;
   }
}
@@ -722,16 +722,69 @@
 ontext;%0A
+import org.jboss.forge.addon.ui.context.UISelection;%0A
 import o
@@ -1963,42 +1963,8 @@
  %7D%0A%0A
-   @SuppressWarnings(%22unchecked%22)%0A
    @
@@ -2882,22 +2882,30 @@
         
-Object
+UISelection%3C?%3E
  selecti
@@ -2984,147 +2984,72 @@
 null
-)%0A         %7B%0A            if (selection instanceof Iterable%3C?%3E)%0A            %7B%0A               for (Resource%3C?%3E item : (Iterable%3CResource%3C?%3E%3E)
+ && !selection.isEmpty())%0A         %7B%0A            Object result =
  sel
@@ -3050,25 +3050,31 @@
  = selection
-)
+.get();
 %0A           
@@ -3078,217 +3078,42 @@
     
-   %7B%0A                  if (item != null)%0A                  %7B%0A                     shell.setCurrentResource(item);%0A                     break;%0A                  %7D%0A               %7D%0A            %7D%0A            else
+if (result instanceof Resource%3C?%3E)
 %0A   
@@ -3177,25 +3177,22 @@
 rce%3C?%3E) 
-selection
+result
 );%0A     

Fix for selection