/**
 * 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.hcatalog.utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.util.GenericOptionsParser;
import org.apache.hcatalog.common.HCatConstants;
import org.apache.hcatalog.data.DefaultHCatRecord;
import org.apache.hcatalog.data.HCatRecord;
import org.apache.hcatalog.data.schema.HCatFieldSchema;
import org.apache.hcatalog.data.schema.HCatSchema;
import org.apache.hcatalog.mapreduce.HCatInputFormat;
import org.apache.hcatalog.mapreduce.HCatOutputFormat;
import org.apache.hcatalog.mapreduce.InputJobInfo;
import org.apache.hcatalog.mapreduce.OutputJobInfo;

/**
 * This is a map reduce test for testing hcat which goes against the "numbers"
 * table and writes data to another table. It reads data from numbers which
 * is an unpartitioned table and adds 10 to each field. It stores the result into
 * the datestamp='20100101' partition of the numbers_part_empty_initially table if the second
 * command line arg is "part". If the second cmdline arg is "nopart" then the
 * result is stored into the 'numbers_nopart_empty_initially' (unpartitioned) table.
 * If the second cmdline arg is "nopart_pig", then the result is stored into the
 * 'numbers_nopart_pig_empty_initially' (unpartitioned) table with the tinyint
 * and smallint columns in "numbers" being stored as "int" (since pig cannot handle
 * tinyint and smallint)
 * 
 * Usage: hadoop jar storenumbers <serveruri> <part|nopart|nopart_pig> <-libjars hive-hcat jar>
        If the second argument is "part" data is written to datestamp = '2010101' partition of the numbers_part_empty_initially table.
        If the second argument is "nopart", data is written to the unpartitioned numbers_nopart_empty_initially table.
        If the second argument is "nopart_pig", data is written to the unpartitioned numbers_nopart_pig_empty_initially table.
        The hcat jar location should be specified as file://<full path to jar>
 */
public class StoreNumbers {

    private static final String NUMBERS_PARTITIONED_TABLE_NAME = "numbers_part_empty_initially";
    private static final String NUMBERS_TABLE_NAME = "numbers";
    private static final String NUMBERS_NON_PARTITIONED_TABLE_NAME = "numbers_nopart_empty_initially";
    private static final String NUMBERS_NON_PARTITIONED_PIG_TABLE_NAME = "numbers_nopart_pig_empty_initially";
    private static final String IS_PIG_NON_PART_TABLE = "is.pig.non.part.table";
    
  public static class SumMapper 
       extends Mapper<WritableComparable, HCatRecord, WritableComparable, HCatRecord>{
      
      Integer intnum1000;
      // though id is given as a Short by hcat, the map will emit it as an
      // IntWritable so we can just sum in the reduce
      Short id;
      
      // though intnum5 is handed as a Byte by hcat, the map() will emit it as
      // an IntWritable so we can just sum in the reduce
      Byte intnum5;
      Integer intnum100;
      Integer intnum;
      Long longnum;
      Float floatnum;
      Double doublenum;
    @Override
  protected void map(WritableComparable key, HCatRecord value, 
          org.apache.hadoop.mapreduce.Mapper<WritableComparable,HCatRecord,
          WritableComparable,HCatRecord>.Context context) 
    throws IOException ,InterruptedException {
        boolean isnoPartPig = context.getConfiguration().getBoolean(IS_PIG_NON_PART_TABLE, false);
        intnum1000 = ((Integer)value.get(0));
        id = ((Short) value.get(1));
        intnum5 = (((Byte)value.get(2)));
        intnum100 = (((Integer) value.get(3)));
        intnum = ((Integer) value.get(4));
        longnum = ((Long) value.get(5));
        floatnum = ((Float) value.get(6));
        doublenum = ((Double) value.get(7));
        HCatRecord output = new DefaultHCatRecord(8);
        output.set(0, intnum1000 + 10);
        if(isnoPartPig)
        {
            output.set(1, ((int)(id + 10)));
        } else {
            output.set(1, ((short)(id + 10)));
        }
        if(isnoPartPig) {
            output.set(2,  (int)(intnum5 + 10));
        } else {
            output.set(2, (byte) (intnum5 + 10));
        }
        
        output.set(3, intnum100 + 10);
        output.set(4, intnum + 10);
        output.set(5, (long) (longnum + 10));
        output.set(6, (float) (floatnum + 10));
        output.set(7, (double) (doublenum + 10));
        for(int i = 0; i < 8; i++) {
            System.err.println("XXX: class:" + output.get(i).getClass());
        }
        context.write(new IntWritable(0), output);

    }
  }
  
  
   public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    args = new GenericOptionsParser(conf, args).getRemainingArgs();
    String[] otherArgs = new String[2];
    int j = 0;
    for(int i = 0; i < args.length; i++) {
        if(args[i].equals("-libjars")) {
            // generic options parser doesn't seem to work!
            conf.set("tmpjars", args[i+1]);
            i = i+1; // skip it , the for loop will skip its value                
        } else {
            otherArgs[j++] = args[i];
        }
    }
    if (otherArgs.length != 2) {
      usage();
    }
    String serverUri = otherArgs[0];
    if(otherArgs[1] == null || (
            !otherArgs[1].equalsIgnoreCase("part") && !otherArgs[1].equalsIgnoreCase("nopart"))
            && !otherArgs[1].equalsIgnoreCase("nopart_pig")) {
        usage();
    }
    boolean writeToPartitionedTable = (otherArgs[1].equalsIgnoreCase("part"));
    boolean writeToNonPartPigTable = (otherArgs[1].equalsIgnoreCase("nopart_pig"));
    String tableName = NUMBERS_TABLE_NAME;
    String dbName = "default";
    Map<String, String> outputPartitionKvps = new HashMap<String, String>();
    String outputTableName = null;
    conf.set(IS_PIG_NON_PART_TABLE, "false");
    if(writeToPartitionedTable) {
        outputTableName = NUMBERS_PARTITIONED_TABLE_NAME;
        outputPartitionKvps.put("datestamp", "20100101");
    } else {
        if(writeToNonPartPigTable) {
            conf.set(IS_PIG_NON_PART_TABLE, "true");
            outputTableName = NUMBERS_NON_PARTITIONED_PIG_TABLE_NAME;
        } else {
            outputTableName = NUMBERS_NON_PARTITIONED_TABLE_NAME;
        }
        // test with null or empty randomly
        if(new Random().nextInt(2) == 0) {
            outputPartitionKvps = null;
        }
    }
    
    String principalID = System.getProperty(HCatConstants.HCAT_METASTORE_PRINCIPAL);
    if(principalID != null)
    conf.set(HCatConstants.HCAT_METASTORE_PRINCIPAL, principalID);
    Job job = new Job(conf, "storenumbers");
    
    // initialize HCatInputFormat
    HCatInputFormat.setInput(job, InputJobInfo.create(
    		dbName, tableName, null));
    // initialize HCatOutputFormat
    HCatOutputFormat.setOutput(job, OutputJobInfo.create(
            dbName, outputTableName, outputPartitionKvps));
    // test with and without specifying schema randomly
    HCatSchema s = HCatInputFormat.getTableSchema(job);
    if(writeToNonPartPigTable) {
        List<HCatFieldSchema> newHfsList = new ArrayList<HCatFieldSchema>();
        // change smallint and tinyint to int
        for(HCatFieldSchema hfs: s.getFields()){
            if(hfs.getTypeString().equals("smallint")) {
                newHfsList.add(new HCatFieldSchema(hfs.getName(), 
                        HCatFieldSchema.Type.INT, hfs.getComment()));
            } else if(hfs.getTypeString().equals("tinyint")) {
                newHfsList.add(new HCatFieldSchema(hfs.getName(), 
                        HCatFieldSchema.Type.INT, hfs.getComment()));
            } else {
                newHfsList.add(hfs);
            }
        }
        s = new HCatSchema(newHfsList);
    } 
    HCatOutputFormat.setSchema(job, s);
    
    
    job.setInputFormatClass(HCatInputFormat.class);
    job.setOutputFormatClass(HCatOutputFormat.class);
    job.setJarByClass(StoreNumbers.class);
    job.setMapperClass(SumMapper.class);
    job.setOutputKeyClass(IntWritable.class);
    job.setNumReduceTasks(0);
    job.setOutputValueClass(DefaultHCatRecord.class);
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }


    /**
     * 
     */
    private static void usage() {
        System.err.println("Usage: hadoop jar storenumbers <serveruri> <part|nopart|nopart_pig> <-libjars hive-hcat jar>\n" +
                "\tIf the second argument is \"part\" data is written to datestamp = '2010101' partition of " +
                "the numbers_part_empty_initially table.\n\tIf the second argument is \"nopart\", data is written to " +
                "the unpartitioned numbers_nopart_empty_initially table.\n\tIf the second argument is \"nopart_pig\", " +
                "data is written to the unpartitioned numbers_nopart_pig_empty_initially table.\nt" +
        "The hcat jar location should be specified as file://<full path to jar>\n");
    System.exit(2);
        
    }
   

}
