package voldemort.performance;

import joptsimple.OptionParser;
import joptsimple.OptionSet;
import voldemort.client.ClientConfig;
import voldemort.client.SocketStoreClientFactory;
import voldemort.client.StoreClient;
import voldemort.client.StoreClientFactory;
import voldemort.utils.CmdUtils;
import voldemort.utils.PseudoRandom;

import java.util.List;

/**
 * @author afeinber
 * Generate data pseudo-random data with desired parameters on a remote cluster
 */
public class RemoteDataGenerator {
    private final PseudoRandom prng = new PseudoRandom();
    private final String url;
    private final String storeName;
    private final int workers;
    private static final int MAX_WORKERS = 8;

    public RemoteDataGenerator(String url, String storeName, int workers) {
        this.workers = workers;
        this.url = url;
        this.storeName = storeName;
    }

    /**
     * Populate the store with {@param requests} key-value pairs with key of size,
     * appending {@param postfix} for uniqueness.
     *
     * {@param keySize} bytes and value of size {@param valueSize} bytes
     * @param requests How many key-value pairs to generate
     * @param keySize Size (in bytes) of the key
     * @param valueSize Size (in bytes) of the value
     * @param postfix Postfix to append (for uniqueness)
     */
    public void
    generateData(int requests, int keySize, int valueSize, String postfix) {
        StoreClientFactory storeClientFactory = new
                SocketStoreClientFactory(new ClientConfig()
                .setBootstrapUrls(url)
                .setMaxThreads(workers));
        StoreClient<String,String> client = storeClientFactory.getStoreClient(storeName);

        for (int i=0; i < requests; i++) {
            StringBuilder keyBuilder = new StringBuilder(makeString(keySize))
                    .append(i);
            StringBuilder valueBuilder = new StringBuilder(makeString(valueSize))
                    .append(i);
            if (postfix != null) {
                keyBuilder.append(postfix);
            }
            try {
                client.put(keyBuilder.toString(), valueBuilder.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * Pads a string with random longs until it reaches {@param size} bytes
     * @param size Desired bytes in the string
     * @return String of length >= {@param size} composed of pseudo-random longs
     */
    protected String makeString(int size) {
        StringBuilder output = new StringBuilder();

        // Java Strings are two bytes per character
        while(output.length() < size*2) {
            output.append(prng.random());
        }

        return output.toString();
    }

    public static void main (String[] args) {
        OptionParser parser = new OptionParser();
        parser.accepts("k", "key size")
                .withRequiredArg()
                .ofType(Integer.class);
        parser.accepts("v", "value size")
                .withRequiredArg()
                .ofType(Integer.class);
        parser.accepts("p", "prefix")
                .withRequiredArg();

        OptionSet options = parser.parse(args);
        List<String> nonOptions = options.nonOptionArguments();
        if (nonOptions.size() != 3) {

        }
        String url = nonOptions.get(0);
        String storeName = nonOptions.get(1);

        int requests = Integer.parseInt(nonOptions.get(2));
        int keySize = CmdUtils.valueOf(options, "k", 128);
        int valueSize = CmdUtils.valueOf(options, "v", 256);
        int workers = CmdUtils.valueOf(options, "threads", MAX_WORKERS);
        String postfix = (String) (options.has("p") ?
                options.valueOf("p") :
                null);
        RemoteDataGenerator rdg = new RemoteDataGenerator(url, storeName, workers);
        rdg.generateData(requests, keySize, valueSize, postfix);
    }
}

@@ -326,16 +326,72 @@
 andom;%0A%0A
+import java.io.IOException;%0Aimport java.io.PrintStream;%0A
 import j
@@ -760,169 +760,763 @@
    p
-ublic RemoteDataGenerator(String url, String storeName, int workers) %7B%0A        this.workers = workers;%0A        this.url = url;%0A        this.storeName = storeName
+rivate static final String usageStr =%0A            %22Usage: $VOLDEMORT_HOME/bin/generate-data.sh %5C%5C%5Cn%22 +%0A                    %22%5Ct %5Boptions%5D bootstrapUrl storeName%22;%0A%0A    public RemoteDataGenerator(String url, String storeName, int workers) %7B%0A        this.workers = workers;%0A        this.url = url;%0A        this.storeName = storeName;%0A    %7D%0A%0A    public static void printUsage(PrintStream out, OptionParser parser, String msg) throws%0A            IOException %7B%0A        out.println(msg);%0A        out.println(usageStr);%0A        parser.printHelpOn(out);%0A        System.exit(1);%0A    %7D%0A%0A    public static void printUsage(PrintStream out, OptionParser parser) throws IOException %7B%0A        out.println(usageStr);%0A        parser.printHelpOn(out);%0A        System.exit(1)
 ;%0A  
@@ -3452,16 +3452,35 @@
 %5B%5D args)
+ throws IOException
  %7B%0A     
@@ -3939,24 +3939,25 @@
 rguments();%0A
+%0A
         if (
@@ -3982,16 +3982,59 @@
 != 3) %7B%0A
+            printUsage(System.err, parser);
 %0A       
@@ -4028,32 +4028,41 @@
 ser);%0A        %7D%0A
+        %0A
         String u

Work on remote data generator.