/**
 * 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 org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.apache.hcatalog.common.HCatConstants;
import org.apache.hcatalog.data.DefaultHCatRecord;
import org.apache.hcatalog.data.HCatRecord;
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. It performs a group by on the first column and a SUM operation on the
 * other columns. This is to simulate a typical operation in a map reduce
 * program to test that hcat hands the right data to the map reduce program
 *
 * Usage: hadoop jar sumnumbers <serveruri> <output dir> <-libjars hive-hcat
 * jar> The <tab|ctrla> argument controls the output delimiter The hcat jar
 * location should be specified as file://<full path to jar>
 */
public class HBaseReadWrite extends Configured implements Tool {

    public static class HBaseWriteMap extends
        Mapper<LongWritable, Text, Text, Text> {

        String name;
        String age;
        String gpa;

        @Override
        protected void map(
            LongWritable key,
            Text value,
            org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, Text, Text>.Context context)
            throws IOException, InterruptedException {
            String line = value.toString();
            String[] tokens = line.split("\t");
            name = tokens[0];

            context.write(new Text(name), value);
        }
    }


    public static class HBaseWriteReduce extends
        Reducer<Text, Text, WritableComparable, HCatRecord> {

        String name;
        String age;
        String gpa;

        @Override
        protected void reduce(Text key, Iterable<Text> values, Context context)
            throws IOException, InterruptedException {
            name = key.toString();
            int count = 0;
            double sum = 0;
            for (Text value : values) {
                String line = value.toString();
                String[] tokens = line.split("\t");
                name = tokens[0];
                age = tokens[1];
                gpa = tokens[2];

                count++;
                sum += Double.parseDouble(gpa.toString());
            }

            HCatRecord record = new DefaultHCatRecord(2);
            record.set(0, name);
            record.set(1, Double.toString(sum));

            context.write(null, record);
        }
    }

    public static class HBaseReadMap extends
        Mapper<WritableComparable, HCatRecord, Text, Text> {

        String name;
        String age;
        String gpa;

        @Override
        protected void map(
            WritableComparable key,
            HCatRecord value,
            org.apache.hadoop.mapreduce.Mapper<WritableComparable, HCatRecord, Text, Text>.Context context)
            throws IOException, InterruptedException {
            name = (String) value.get(0);
            gpa = (String) value.get(1);
            context.write(new Text(name), new Text(gpa));
        }
    }


    public int run(String[] args) throws Exception {
        Configuration conf = getConf();
        args = new GenericOptionsParser(conf, args).getRemainingArgs();

        String serverUri = args[0];
        String inputDir = args[1];
        String tableName = args[2];
        String outputDir = args[3];
        String dbName = null;

        String principalID = System
            .getProperty(HCatConstants.HCAT_METASTORE_PRINCIPAL);
        if (principalID != null)
            conf.set(HCatConstants.HCAT_METASTORE_PRINCIPAL, principalID);
        conf.set("hcat.hbase.output.bulkMode", "false");
        Job job = new Job(conf, "HBaseWrite");
        FileInputFormat.setInputPaths(job, inputDir);

        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(HCatOutputFormat.class);
        job.setJarByClass(HBaseReadWrite.class);
        job.setMapperClass(HBaseWriteMap.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);
        job.setReducerClass(HBaseWriteReduce.class);
        job.setOutputKeyClass(WritableComparable.class);
        job.setOutputValueClass(DefaultHCatRecord.class);
        HCatOutputFormat.setOutput(job, OutputJobInfo.create(dbName,
            tableName, null));

        boolean succ = job.waitForCompletion(true);

        if (!succ) return 1;

        job = new Job(conf, "HBaseRead");
        HCatInputFormat.setInput(job, InputJobInfo.create(dbName, tableName,
            null));

        job.setInputFormatClass(HCatInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);
        job.setJarByClass(HBaseReadWrite.class);
        job.setMapperClass(HBaseReadMap.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        job.setNumReduceTasks(0);
        TextOutputFormat.setOutputPath(job, new Path(outputDir));

        succ = job.waitForCompletion(true);

        if (!succ) return 2;

        return 0;
    }

    public static void main(String[] args) throws Exception {
        int exitCode = ToolRunner.run(new HBaseReadWrite(), args);
        System.exit(exitCode);
    }
}

