/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.hadoop.hive.tools.generate;

import java.util.Properties;
import java.util.Random;
import java.io.FileWriter;
import java.io.PrintWriter;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.compress.DefaultCodec;

import org.apache.hadoop.hive.serde2.columnar.BytesRefArrayWritable;
import org.apache.hadoop.hive.serde2.columnar.BytesRefWritable;
import org.apache.hadoop.hive.ql.io.RCFile;
import org.apache.hadoop.hive.ql.io.RCFileOutputFormat;

/**
 * Generate RCFile test data
 *
 */
public class RCFileGenerator {

    private static Configuration conf = new Configuration();
    private static Path basedir;
    private static FileSystem fs;
    private static Properties tbl;
    private static Random rand;

    private static Path getFile(String filename) throws Exception {
        return new Path(basedir, filename);
    }

    private static String[] firstName = {"alice", "bob", "calvin", "david",
        "ethan", "fred", "gabriella", "holly", "irene", "jessica", "katie",
        "luke", "mike", "nick", "oscar", "priscilla", "quinn", "rachel",
        "sarah", "tom", "ulysses", "victor", "wendy", "xavier", "yuri",
        "zach"};

    private static String[] lastName = {"allen", "brown", "carson",
        "davidson", "ellison", "falkner", "garcia", "hernandez", "ichabod",
        "johnson", "king", "laertes", "miller", "nixon", "ovid", "polk",
        "quirinius", "robinson", "steinbeck", "thompson", "underhill",
        "van buren", "white", "xylophone", "young", "zipper"};

    private static String randomName() {
        StringBuffer buf =
                new StringBuffer(firstName[rand.nextInt(firstName.length)]);
        buf.append(' ');
        buf.append(lastName[rand.nextInt(lastName.length)]);
        return buf.toString();
    }

    private static int randomAge() {
        return rand.nextInt(60) + 18;
    }

    private static double randomGpa() {
        return 4 * rand.nextFloat();
    }

    private static String[] registration = {"democrat", "green",
        "independent", "libertarian", "republican", "socialist"};

    private static String randomRegistration() {
        return registration[rand.nextInt(registration.length)];
    }

    private static double randomContribution() {
        return rand.nextFloat() * 1000;
    }

    private static byte[] randomMap() throws Exception {
        int len = rand.nextInt(5) + 1;

        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < len; i++) {
            if (i != 0) buf.append('\u0002');
            buf.append(firstName[rand.nextInt(26)]);
            buf.append('\u0003');
            buf.append(lastName[rand.nextInt(26)]);
        }
        return buf.toString().getBytes("UTF-8");
    }

    private static byte[] randomArray() throws Exception {
        int len = rand.nextInt(5) + 1;

        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < len; i++) {
            if (i != 0) buf.append('\u0002');
            buf.append(Integer.valueOf(randomAge()).toString());
            buf.append('\u0003');
            buf.append(randomName());
        }
        return buf.toString().getBytes("UTF-8");
    }

    private static void usage() {
        System.err.println("Usage: rcfilegen format number_of_rows " +
                "output_file plain_output_file");
        System.err.println("  format one of:  student voter alltypes");
        System.exit(1);
    }

    public static void main(String[] args) throws Exception {
        if (args.length != 4) usage();

        String format = args[0];
        int numRows = Integer.valueOf(args[1]);
        if (numRows < 1) usage();
        String output = args[2];
        String plainOutput = args[3];

        fs = FileSystem.getLocal(conf);
        basedir = new Path(".");

        genData(format, numRows, output, plainOutput);
    }

    private static void genData(String format,
                                int numRows,
                                String output, String plainOutput) throws Exception {
        int numFields = 0;
        if (format.equals("student")) {
            rand = new Random(numRows);
            numFields = 3;
        } else if (format.equals("voter")) {
            rand = new Random(1000000000 + numRows);
            numFields = 4;
        } else if (format.equals("alltypes")) {
            rand = new Random(2000000000L + numRows);
            numFields = 10;
        }

        RCFileOutputFormat.setColumnNumber(conf, numFields);
        RCFile.Writer writer = new RCFile.Writer(fs, conf, getFile(output),
                null, new DefaultCodec());

        PrintWriter pw = new PrintWriter(new FileWriter(plainOutput));

        for (int j = 0; j < numRows; j++) {
            BytesRefArrayWritable row = new BytesRefArrayWritable(numFields);

            byte[][] fields = null;

            if (format.equals("student")) {
                byte[][] f = {
                        randomName().getBytes("UTF-8"),
                        Integer.valueOf(randomAge()).toString().getBytes("UTF-8"),
                        Double.valueOf(randomGpa()).toString().getBytes("UTF-8")
                };
                fields = f;
            } else if (format.equals("voter")) {
                byte[][] f = {
                        randomName().getBytes("UTF-8"),
                        Integer.valueOf(randomAge()).toString().getBytes("UTF-8"),
                        randomRegistration().getBytes("UTF-8"),
                        Double.valueOf(randomContribution()).toString().getBytes("UTF-8")
                };
                fields = f;
            } else if (format.equals("alltypes")) {
                byte[][] f = {
                        Integer.valueOf(rand.nextInt(Byte.MAX_VALUE)).toString().getBytes("UTF-8"),
                        Integer.valueOf(rand.nextInt(Short.MAX_VALUE)).toString().getBytes("UTF-8"),
                        Integer.valueOf(rand.nextInt()).toString().getBytes("UTF-8"),
                        Long.valueOf(rand.nextLong()).toString().getBytes("UTF-8"),
                        Float.valueOf(rand.nextFloat() * 1000).toString().getBytes("UTF-8"),
                        Double.valueOf(rand.nextDouble() * 1000000).toString().getBytes("UTF-8"),
                        randomName().getBytes("UTF-8"),
                        randomMap(),
                        randomArray()
                };
                fields = f;
            }


            for (int i = 0; i < fields.length; i++) {
                BytesRefWritable field = new BytesRefWritable(fields[i], 0,
                        fields[i].length);
                row.set(i, field);
                pw.print(new String(fields[i]));
                if (i != fields.length - 1)
                    pw.print("\t");
                else
                    pw.println();
            }

            writer.append(row);
        }

        writer.close();
        pw.close();
    }
}

