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

import java.io.IOException;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.mapred.FileOutputCommitter;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.JobContext;
import org.apache.hadoop.mapred.OutputCommitter;
import org.apache.hadoop.mapred.RecordWriter;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.SequenceFileOutputFormat;
import org.apache.hadoop.mapred.TaskAttemptContext;
import org.apache.hadoop.util.Progressable;
import org.apache.hcatalog.hbase.snapshot.RevisionManager;

/**
 * Class which imports data into HBase via it's "bulk load" feature. Wherein
 * regions are created by the MR job using HFileOutputFormat and then later
 * "moved" into the appropriate region server.
 */
class HBaseBulkOutputFormat extends HBaseBaseOutputFormat {

    private final static ImmutableBytesWritable EMPTY_LIST = new ImmutableBytesWritable(
        new byte[0]);
    private SequenceFileOutputFormat<WritableComparable<?>, Put> baseOutputFormat;

    public HBaseBulkOutputFormat() {
        baseOutputFormat = new SequenceFileOutputFormat<WritableComparable<?>, Put>();
    }

    @Override
    public void checkOutputSpecs(FileSystem ignored, JobConf job)
        throws IOException {
        baseOutputFormat.checkOutputSpecs(ignored, job);
        HBaseUtil.addHBaseDelegationToken(job);
        addJTDelegationToken(job);
    }

    @Override
    public RecordWriter<WritableComparable<?>, Put> getRecordWriter(
        FileSystem ignored, JobConf job, String name, Progressable progress)
        throws IOException {
        job.setOutputKeyClass(ImmutableBytesWritable.class);
        job.setOutputValueClass(Put.class);
        long version = HBaseRevisionManagerUtil.getOutputRevision(job);
        return new HBaseBulkRecordWriter(baseOutputFormat.getRecordWriter(
            ignored, job, name, progress), version);
    }

    private void addJTDelegationToken(JobConf job) throws IOException {
        // Get jobTracker delegation token if security is enabled
        // we need to launch the ImportSequenceFile job
        if (User.isSecurityEnabled()) {
            JobClient jobClient = new JobClient(new JobConf(job));
            try {
                job.getCredentials().addToken(new Text("my mr token"),
                    jobClient.getDelegationToken(null));
            } catch (InterruptedException e) {
                throw new IOException("Error while getting JT delegation token", e);
            }
        }
    }

    private static class HBaseBulkRecordWriter implements
        RecordWriter<WritableComparable<?>, Put> {

        private RecordWriter<WritableComparable<?>, Put> baseWriter;
        private final Long outputVersion;

        public HBaseBulkRecordWriter(
            RecordWriter<WritableComparable<?>, Put> baseWriter,
            Long outputVersion) {
            this.baseWriter = baseWriter;
            this.outputVersion = outputVersion;
        }

        @Override
        public void write(WritableComparable<?> key, Put value)
            throws IOException {
            Put put = value;
            if (outputVersion != null) {
                put = new Put(value.getRow(), outputVersion.longValue());
                for (List<KeyValue> row : value.getFamilyMap().values()) {
                    for (KeyValue el : row) {
                        put.add(el.getFamily(), el.getQualifier(), el.getValue());
                    }
                }
            }
            // we ignore the key
            baseWriter.write(EMPTY_LIST, put);
        }

        @Override
        public void close(Reporter reporter) throws IOException {
            baseWriter.close(reporter);
        }
    }

    public static class HBaseBulkOutputCommitter extends OutputCommitter {

        private final OutputCommitter baseOutputCommitter;

        public HBaseBulkOutputCommitter() {
            baseOutputCommitter = new FileOutputCommitter();
        }

        @Override
        public void abortTask(TaskAttemptContext taskContext)
            throws IOException {
            baseOutputCommitter.abortTask(taskContext);
        }

        @Override
        public void commitTask(TaskAttemptContext taskContext)
            throws IOException {
            baseOutputCommitter.commitTask(taskContext);
        }

        @Override
        public boolean needsTaskCommit(TaskAttemptContext taskContext)
            throws IOException {
            return baseOutputCommitter.needsTaskCommit(taskContext);
        }

        @Override
        public void setupJob(JobContext jobContext) throws IOException {
            baseOutputCommitter.setupJob(jobContext);
        }

        @Override
        public void setupTask(TaskAttemptContext taskContext)
            throws IOException {
            baseOutputCommitter.setupTask(taskContext);
        }

        @Override
        public void abortJob(JobContext jobContext, int status)
            throws IOException {
            baseOutputCommitter.abortJob(jobContext, status);
            RevisionManager rm = null;
            try {
                rm = HBaseRevisionManagerUtil
                    .getOpenedRevisionManager(jobContext.getConfiguration());
                rm.abortWriteTransaction(HBaseRevisionManagerUtil
                    .getWriteTransaction(jobContext.getConfiguration()));
            } finally {
                cleanIntermediate(jobContext);
                if (rm != null)
                    rm.close();
            }
        }

        @Override
        public void commitJob(JobContext jobContext) throws IOException {
            baseOutputCommitter.commitJob(jobContext);
            RevisionManager rm = null;
            try {
                Configuration conf = jobContext.getConfiguration();
                Path srcPath = FileOutputFormat.getOutputPath(jobContext.getJobConf());
                if (!FileSystem.get(conf).exists(srcPath)) {
                    throw new IOException("Failed to bulk import hfiles. " +
                        "Intermediate data directory is cleaned up or missing. " +
                        "Please look at the bulk import job if it exists for failure reason");
                }
                Path destPath = new Path(srcPath.getParent(), srcPath.getName() + "_hfiles");
                boolean success = ImportSequenceFile.runJob(jobContext,
                    conf.get(HBaseConstants.PROPERTY_OUTPUT_TABLE_NAME_KEY),
                    srcPath,
                    destPath);
                if (!success) {
                    cleanIntermediate(jobContext);
                    throw new IOException("Failed to bulk import hfiles." +
                        " Please look at the bulk import job for failure reason");
                }
                rm = HBaseRevisionManagerUtil.getOpenedRevisionManager(conf);
                rm.commitWriteTransaction(HBaseRevisionManagerUtil.getWriteTransaction(conf));
                cleanIntermediate(jobContext);
            } finally {
                if (rm != null)
                    rm.close();
            }
        }

        private void cleanIntermediate(JobContext jobContext)
            throws IOException {
            FileSystem fs = FileSystem.get(jobContext.getConfiguration());
            fs.delete(FileOutputFormat.getOutputPath(jobContext.getJobConf()), true);
        }
    }
}
