package unstar;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import java.awt.AWTException;
import java.io.File;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;


/**
 * The main class.
 */
public final class Launcher {

    /** Codes source file name. */
    @Parameter(names = "-f", description = "Get codes from a file.")
    private String file;

    /** Codes source host name. */
    @Parameter(names = "-s", description = "Get codes from code server.")
    private String host;

    /**
     * Hidden constructor.
     */
    private Launcher() {
    }

    /**
     * The main method.
     * @param args  the command line arguments
     */
    public static void main(final String[] args) {
        /* Command line parsing. */
        Launcher params = new Launcher();
        try {
            new JCommander(params, args);
        } catch (ParameterException e) {
            System.err.println("error: " + e.getMessage());
            usage(-1);
        }
        CodeProvider provider = null;
        try {
            if (params.file != null) {
                provider = new FileCodeProvider(new File(params.file));
            } else if (params.host != null) {
                int port = unstar.server.Server.DEFAULT_PORT;
                provider = new TcpCodeProvider(params.host, port);
            } else {
                System.err.println("error: must select exactly one source");
                usage(-1);
            }
        } catch (Exception e) {
            System.err.println("error: " + e.getMessage());
            System.exit(-1);
        }

        /* Set up the logger. */
        try {
            Handler handler = new FileHandler("cracker.log");
            Logger.getLogger("").addHandler(handler);
        } catch (IOException e) {
            System.out.println("Failed to create log file: " + e.getMessage());
            System.exit(-1);
        }
        DeadSimpleFormatter.load();

        /* Start testing codes. */
        try {
            new Cracker(provider).run();
        } catch (AWTException e) {
            System.err.println(e);
            System.exit(-1);
        }
    }

    /**
     * Print usage and exit.
     * @param status  the exit status to use
     */
    private static void usage(final int status) {
        new JCommander(new Launcher()).usage();
        System.exit(status);
    }
}

@@ -646,16 +646,195 @@
  host;%0A%0A
+    /** Codes from generation. */%0A    @Parameter(names = %22-g%22, description =%0A               %22Get codes by generation (range format %5C%22START:END%5C%22).%22)%0A    private String generate;%0A%0A
     /**%0A
@@ -1344,16 +1344,40 @@
 = null;%0A
+        int pcount = 0;%0A
         
@@ -1489,24 +1489,50 @@
 ams.file));%0A
+                pcount++;%0A
             
@@ -1706,22 +1706,556 @@
         
-%7D else
+    pcount++;%0A            %7D else if (params.generate != null) %7B%0A                try %7B%0A                    String start = params.generate.split(%22:%22)%5B0%5D;%0A                    String end = params.generate.split(%22:%22)%5B1%5D;%0A                    provider = new GeneratorCodeProvider(start, end);%0A                    pcount++;%0A                %7D catch (ArrayIndexOutOfBoundsException e) %7B%0A                    System.err.println(%22error: bad generator format%22);%0A                    usage(-1);%0A                %7D%0A            %7D%0A%0A            if (pcount != 1)
  %7B%0A     
@@ -2439,37 +2439,24 @@
 error: %22 + e
-.getMessage()
 );%0A         

Add generator command line argument.