/**
 * 
 */
package org.zanata.client.commands;

import java.io.PrintStream;

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Sean Flanigan <sflaniga@redhat.com>
 *
 */
public class ArgsUtil
{
   private static final Logger log = LoggerFactory.getLogger(ArgsUtil.class);
   private final AppAbortStrategy abortStrategy;
   private final PrintStream out;
   private final PrintStream err;
   private final String clientName;

   public ArgsUtil(AppAbortStrategy strategy, PrintStream out, PrintStream err, String clientName)
   {
      this.abortStrategy = strategy;
      this.out = out;
      this.err = err;
      this.clientName = clientName;
   }

   public void process(String[] args, BasicOptions opts)
   {
      log.debug("process(args: {}, opts: {})", args, opts);
      CmdLineParser parser = new CmdLineParser(opts);

      try
      {
         parser.setUsageWidth(Integer.parseInt(System.getenv("COLUMNS")));
      }
      catch (Exception e)
      {
         parser.setUsageWidth(120);
      }
      try
      {
         parser.parseArgument(args);
      }
      catch (CmdLineException e)
      {
         if (!opts.getHelp() && args.length != 0)
         {
            err.println(e.getMessage());
            printHelp(opts, err);
            parser.printUsage(err);
            abortStrategy.abort(e);
         }
      }

      if (opts.getHelp() || args.length == 0)
      {
         printHelp(opts, out);
         parser.printUsage(out);
         return;
      }
      // while loading config, we use the global logging options
      setLogLevels(opts);

      try
      {
         if (opts instanceof ConfigurableOptions)
            OptionsUtil.applyConfigFiles((ConfigurableOptions) opts);
         ZanataCommand cmd = opts.initCommand();
         // just in case the logging options were changed by a config file:
         setLogLevels(opts);
         if (opts.getErrors())
         {
            log.info("Error stacktraces are turned on.");
         }
         cmd.run();
      }
      catch (Exception e)
      {
         handleException(e, opts.getErrors(), abortStrategy);
      }
   }

   private static void setLogLevels(BasicOptions opts)
   {
      if (opts.getDebug())
      {
         enableDebugLogging();
      }
      else if (opts.getQuiet())
      {
         enableQuietLogging();
      }
   }

   /**
    * Maven's --debug/-X flag sets the Maven LoggerManager to LEVEL_DEBUG. The
    * slf4j framework doesn't provide any way of doing this, so we have to go to
    * the underlying framework (assumed to be log4j).
    */
   private static void enableDebugLogging()
   {
      org.apache.log4j.Logger root = org.apache.log4j.Logger.getRootLogger();
      root.setLevel(org.apache.log4j.Level.DEBUG);
   }

   /**
    * Maven's --quiet/-q flag sets the Maven LoggerManager to LEVEL_ERROR. The
    * slf4j framework doesn't provide any way of doing this, so we have to go to
    * the underlying framework (assumed to be log4j).
    */
   private static void enableQuietLogging()
   {
      org.apache.log4j.Logger root = org.apache.log4j.Logger.getRootLogger();
      root.setLevel(org.apache.log4j.Level.ERROR);
   }

   private void printHelp(BasicOptions cmd, PrintStream output)
   {
      output.println("Usage: " + clientName + " " + cmd.getCommandName() + " [options]");
      output.println(cmd.getCommandDescription());
      output.println();
   }

   public static void handleException(Exception e, boolean outputErrors, AppAbortStrategy abortStrategy)
   {
      if (outputErrors)
      {
         log.error("Execution failed: ", e);
      }
      else
      {
         log.error("Execution failed: " + e.getMessage());
         log.error("Use -e/--errors for full stack trace (or when reporting bugs)");
      }
      abortStrategy.abort(e);
   }

}

@@ -71,16 +71,83 @@
 tream;%0A%0A
+import org.apache.log4j.Level;%0Aimport org.apache.log4j.LogManager;%0A
 import o
@@ -1887,57 +1887,8 @@
 s);%0A
-         ZanataCommand cmd = opts.initCommand();%0A
     
@@ -2095,24 +2095,73 @@
 %0A         %7D%0A
+         ZanataCommand cmd = opts.initCommand();%0A
          cmd
@@ -2401,32 +2401,36 @@
 bleDebugLogging(
+opts
 );%0A      %7D%0A     
@@ -2492,16 +2492,20 @@
 Logging(
+opts
 );%0A     
@@ -2787,141 +2787,70 @@
 ing(
-)%0A   %7B%0A      org.apache.log4j.Logger root = org.apache.log4j.Logger.getRootLogger();%0A      root.setLevel(org.apache.log4j.Level.DEBUG
+BasicOptions opts)%0A   %7B%0A      setRootLoggerLevel(%22DEBUG%22, opts
 );%0A 
@@ -3128,143 +3128,458 @@
 ing(
-)%0A   %7B%0A      org.apache.log4j.Logger root = org.apache.log4j.Logger.getRootLogger();%0A      root.setLevel(org.apache.log4j.Level.ERROR);
+BasicOptions opts)%0A   %7B%0A      setRootLoggerLevel(%22ERROR%22, opts);%0A   %7D%0A%0A   private static void setRootLoggerLevel(String level, BasicOptions opts)%0A   %7B%0A      try%0A      %7B%0A         LogManager.getRootLogger().setLevel(Level.toLevel(level));%0A      %7D%0A      catch (Exception e)%0A      %7B%0A         System.err.println(%22Unable to change logging level: %22+e.toString());%0A         if (opts.getErrors())%0A         %7B%0A            e.printStackTrace();%0A         %7D%0A      %7D
 %0A   

Improve error handling