/**
 * 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 org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
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.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.data.schema.HCatSchema;
import org.apache.hcatalog.data.schema.HCatFieldSchema;
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 writing to partitioned tables.
 * 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 org.apache.hcatalog.utils.HBaseReadWrite -libjars
 * &lt;hcat_jar&gt; * &lt;serveruri&gt; &lt;input_tablename&gt; &lt;output_tablename&gt; [filter]
 * If filter is given it will be provided as the partition to write to.
 */
public class WriteTextPartitioned extends Configured implements Tool {

    static String filter = null;

    public static class Map extends
        Mapper<WritableComparable, HCatRecord, WritableComparable, HCatRecord> {

        @Override
        protected void map(
            WritableComparable key,
            HCatRecord value,
            org.apache.hadoop.mapreduce.Mapper<WritableComparable, HCatRecord, WritableComparable, HCatRecord>.Context context)
            throws IOException, InterruptedException {
            String name = (String) value.get(0);
            int age = (Integer) value.get(1);
            String ds = (String) value.get(3);

            HCatRecord record = (filter == null ? new DefaultHCatRecord(3) : new DefaultHCatRecord(2));
            record.set(0, name);
            record.set(1, age);
            if (filter == null) record.set(2, ds);

            context.write(null, record);

        }
    }

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

        String serverUri = args[0];
        String inputTableName = args[1];
        String outputTableName = args[2];
        if (args.length > 3) filter = args[3];
        String dbName = null;

        String principalID = System
            .getProperty(HCatConstants.HCAT_METASTORE_PRINCIPAL);
        if (principalID != null)
            conf.set(HCatConstants.HCAT_METASTORE_PRINCIPAL, principalID);
        Job job = new Job(conf, "WriteTextPartitioned");
        HCatInputFormat.setInput(job, InputJobInfo.create(dbName,
            inputTableName, filter));
        // initialize HCatOutputFormat

        job.setInputFormatClass(HCatInputFormat.class);
        job.setJarByClass(WriteTextPartitioned.class);
        job.setMapperClass(Map.class);
        job.setOutputKeyClass(WritableComparable.class);
        job.setOutputValueClass(DefaultHCatRecord.class);
        job.setNumReduceTasks(0);

        java.util.Map<String, String> partitionVals = null;
        if (filter != null) {
            String[] s = filter.split("=");
            String val = s[1].replace('"', ' ').trim();
            partitionVals = new HashMap<String, String>(1);
            partitionVals.put(s[0], val);
        }
        HCatOutputFormat.setOutput(job, OutputJobInfo.create(dbName,
            outputTableName, partitionVals));
        HCatSchema s = HCatInputFormat.getTableSchema(job);
        // Build the schema for this table, which is slightly different than the
        // schema for the input table
        List<HCatFieldSchema> fss = new ArrayList<HCatFieldSchema>(3);
        fss.add(s.get(0));
        fss.add(s.get(1));
        fss.add(s.get(3));
        HCatOutputFormat.setSchema(job, new HCatSchema(fss));
        job.setOutputFormatClass(HCatOutputFormat.class);
        return (job.waitForCompletion(true) ? 0 : 1);
    }

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