/**
 * 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.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.DataInputBuffer;
import org.apache.hadoop.io.DataOutputBuffer;
import org.apache.hadoop.mapred.RecordReader;
import org.apache.hcatalog.common.HCatUtil;
import org.apache.hcatalog.hbase.snapshot.FamilyRevision;
import org.apache.hcatalog.hbase.snapshot.RevisionManager;
import org.apache.hcatalog.hbase.snapshot.TableSnapshot;
import org.apache.hcatalog.mapreduce.InputJobInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class HbaseSnapshotRecordReader implements logic for filtering records
 * based on snapshot.
 */
class HbaseSnapshotRecordReader implements RecordReader<ImmutableBytesWritable, Result> {

    static final Logger LOG = LoggerFactory.getLogger(HbaseSnapshotRecordReader.class);
    private final InputJobInfo inpJobInfo;
    private final Configuration conf;
    private final int maxRevisions = 1;
    private ResultScanner scanner;
    private Scan scan;
    private HTable htable;
    private TableSnapshot snapshot;
    private Iterator<Result> resultItr;
    private Set<Long> allAbortedTransactions;
    private DataOutputBuffer valueOut = new DataOutputBuffer();
    private DataInputBuffer valueIn = new DataInputBuffer();

    HbaseSnapshotRecordReader(InputJobInfo inputJobInfo, Configuration conf) throws IOException {
        this.inpJobInfo = inputJobInfo;
        this.conf = conf;
        String snapshotString = conf.get(HBaseConstants.PROPERTY_TABLE_SNAPSHOT_KEY);
        HCatTableSnapshot hcatSnapshot = (HCatTableSnapshot) HCatUtil
            .deserialize(snapshotString);
        this.snapshot = HBaseRevisionManagerUtil.convertSnapshot(hcatSnapshot,
            inpJobInfo.getTableInfo());
    }

    public void init() throws IOException {
        restart(scan.getStartRow());
    }

    public void restart(byte[] firstRow) throws IOException {
        allAbortedTransactions = getAbortedTransactions(Bytes.toString(htable.getTableName()), scan);
        long maxValidRevision = getMaximumRevision(scan, snapshot);
        while (allAbortedTransactions.contains(maxValidRevision)) {
            maxValidRevision--;
        }
        Scan newScan = new Scan(scan);
        newScan.setStartRow(firstRow);
        //TODO: See if filters in 0.92 can be used to optimize the scan
        //TODO: Consider create a custom snapshot filter
        //TODO: Make min revision a constant in RM
        newScan.setTimeRange(0, maxValidRevision + 1);
        newScan.setMaxVersions();
        this.scanner = this.htable.getScanner(newScan);
        resultItr = this.scanner.iterator();
    }

    private Set<Long> getAbortedTransactions(String tableName, Scan scan) throws IOException {
        Set<Long> abortedTransactions = new HashSet<Long>();
        RevisionManager rm = null;
        try {
            rm = HBaseRevisionManagerUtil.getOpenedRevisionManager(conf);
            byte[][] families = scan.getFamilies();
            for (byte[] familyKey : families) {
                String family = Bytes.toString(familyKey);
                List<FamilyRevision> abortedWriteTransactions = rm.getAbortedWriteTransactions(
                    tableName, family);
                if (abortedWriteTransactions != null) {
                    for (FamilyRevision revision : abortedWriteTransactions) {
                        abortedTransactions.add(revision.getRevision());
                    }
                }
            }
            return abortedTransactions;
        } finally {
            HBaseRevisionManagerUtil.closeRevisionManagerQuietly(rm);
        }
    }

    private long getMaximumRevision(Scan scan, TableSnapshot snapshot) {
        long maxRevision = 0;
        byte[][] families = scan.getFamilies();
        for (byte[] familyKey : families) {
            String family = Bytes.toString(familyKey);
            long revision = snapshot.getRevision(family);
            if (revision > maxRevision)
                maxRevision = revision;
        }
        return maxRevision;
    }

    /*
     * @param htable The HTable ( of HBase) to use for the record reader.
     *
     */
    public void setHTable(HTable htable) {
        this.htable = htable;
    }

    /*
     * @param scan The scan to be used for reading records.
     *
     */
    public void setScan(Scan scan) {
        this.scan = scan;
    }

    @Override
    public ImmutableBytesWritable createKey() {
        return new ImmutableBytesWritable();
    }

    @Override
    public Result createValue() {
        return new Result();
    }

    @Override
    public long getPos() {
        // This should be the ordinal tuple in the range;
        // not clear how to calculate...
        return 0;
    }

    @Override
    public float getProgress() throws IOException {
        // Depends on the total number of tuples
        return 0;
    }

    @Override
    public boolean next(ImmutableBytesWritable key, Result value) throws IOException {
        if (this.resultItr == null) {
            LOG.warn("The HBase result iterator is found null. It is possible"
                + " that the record reader has already been closed.");
        } else {
            while (resultItr.hasNext()) {
                Result temp = resultItr.next();
                Result hbaseRow = prepareResult(temp.list());
                if (hbaseRow != null) {
                    // Update key and value. Currently no way to avoid serialization/de-serialization
                    // as no setters are available.
                    key.set(hbaseRow.getRow());
                    valueOut.reset();
                    hbaseRow.write(valueOut);
                    valueIn.reset(valueOut.getData(), valueOut.getLength());
                    value.readFields(valueIn);
                    return true;
                }

            }
        }
        return false;
    }

    private Result prepareResult(List<KeyValue> keyvalues) {

        List<KeyValue> finalKeyVals = new ArrayList<KeyValue>();
        Map<String, List<KeyValue>> qualValMap = new HashMap<String, List<KeyValue>>();
        for (KeyValue kv : keyvalues) {
            byte[] cf = kv.getFamily();
            byte[] qualifier = kv.getQualifier();
            String key = Bytes.toString(cf) + ":" + Bytes.toString(qualifier);
            List<KeyValue> kvs;
            if (qualValMap.containsKey(key)) {
                kvs = qualValMap.get(key);
            } else {
                kvs = new ArrayList<KeyValue>();
            }

            String family = Bytes.toString(kv.getFamily());
            //Ignore aborted transactions
            if (allAbortedTransactions.contains(kv.getTimestamp())) {
                continue;
            }

            long desiredTS = snapshot.getRevision(family);
            if (kv.getTimestamp() <= desiredTS) {
                kvs.add(kv);
            }
            qualValMap.put(key, kvs);
        }

        Set<String> keys = qualValMap.keySet();
        for (String cf : keys) {
            List<KeyValue> kvs = qualValMap.get(cf);
            if (maxRevisions <= kvs.size()) {
                for (int i = 0; i < maxRevisions; i++) {
                    finalKeyVals.add(kvs.get(i));
                }
            } else {
                finalKeyVals.addAll(kvs);
            }
        }

        if (finalKeyVals.size() == 0) {
            return null;
        } else {
            KeyValue[] kvArray = new KeyValue[finalKeyVals.size()];
            finalKeyVals.toArray(kvArray);
            return new Result(kvArray);
        }
    }

    /*
     * @see org.apache.hadoop.hbase.mapred.TableRecordReader#close()
     */
    @Override
    public void close() {
        this.resultItr = null;
        this.scanner.close();
    }

}
