/**
 * 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.hbase.security.User;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hive.hbase.HBaseSerDe;
import org.apache.hadoop.mapred.JobConf;

class HBaseUtil {

    private HBaseUtil() {
    }

    /**
     * Parses the HBase columns mapping to identify the column families, qualifiers
     * and also caches the byte arrays corresponding to them. One of the HCat table
     * columns maps to the HBase row key, by default the first column.
     *
     * @param columnMapping - the column mapping specification to be parsed
     * @param colFamilies - the list of HBase column family names
     * @param colFamiliesBytes - the corresponding byte array
     * @param colQualifiers - the list of HBase column qualifier names
     * @param colQualifiersBytes - the corresponding byte array
     * @return the row key index in the column names list
     * @throws IOException
     */
    static int parseColumnMapping(
        String columnMapping,
        List<String> colFamilies,
        List<byte[]> colFamiliesBytes,
        List<String> colQualifiers,
        List<byte[]> colQualifiersBytes) throws IOException {

        int rowKeyIndex = -1;

        if (colFamilies == null || colQualifiers == null) {
            throw new IllegalArgumentException("Error: caller must pass in lists for the column families " +
                "and qualifiers.");
        }

        colFamilies.clear();
        colQualifiers.clear();

        if (columnMapping == null) {
            throw new IllegalArgumentException("Error: hbase.columns.mapping missing for this HBase table.");
        }

        if (columnMapping.equals("") || columnMapping.equals(HBaseSerDe.HBASE_KEY_COL)) {
            throw new IllegalArgumentException("Error: hbase.columns.mapping specifies only the HBase table"
                + " row key. A valid Hive-HBase table must specify at least one additional column.");
        }

        String[] mapping = columnMapping.split(",");

        for (int i = 0; i < mapping.length; i++) {
            String elem = mapping[i];
            int idxFirst = elem.indexOf(":");
            int idxLast = elem.lastIndexOf(":");

            if (idxFirst < 0 || !(idxFirst == idxLast)) {
                throw new IllegalArgumentException("Error: the HBase columns mapping contains a badly formed " +
                    "column family, column qualifier specification.");
            }

            if (elem.equals(HBaseSerDe.HBASE_KEY_COL)) {
                rowKeyIndex = i;
                colFamilies.add(elem);
                colQualifiers.add(null);
            } else {
                String[] parts = elem.split(":");
                assert (parts.length > 0 && parts.length <= 2);
                colFamilies.add(parts[0]);

                if (parts.length == 2) {
                    colQualifiers.add(parts[1]);
                } else {
                    colQualifiers.add(null);
                }
            }
        }

        if (rowKeyIndex == -1) {
            colFamilies.add(0, HBaseSerDe.HBASE_KEY_COL);
            colQualifiers.add(0, null);
            rowKeyIndex = 0;
        }

        if (colFamilies.size() != colQualifiers.size()) {
            throw new IOException("Error in parsing the hbase columns mapping.");
        }

        // populate the corresponding byte [] if the client has passed in a non-null list
        if (colFamiliesBytes != null) {
            colFamiliesBytes.clear();

            for (String fam : colFamilies) {
                colFamiliesBytes.add(Bytes.toBytes(fam));
            }
        }

        if (colQualifiersBytes != null) {
            colQualifiersBytes.clear();

            for (String qual : colQualifiers) {
                if (qual == null) {
                    colQualifiersBytes.add(null);
                } else {
                    colQualifiersBytes.add(Bytes.toBytes(qual));
                }
            }
        }

        if (colFamiliesBytes != null && colQualifiersBytes != null) {
            if (colFamiliesBytes.size() != colQualifiersBytes.size()) {
                throw new IOException("Error in caching the bytes for the hbase column families " +
                    "and qualifiers.");
            }
        }

        return rowKeyIndex;
    }

    /**
     * Get delegation token from hbase and add it to JobConf
     * @param job
     * @throws IOException
     */
    static void addHBaseDelegationToken(JobConf job) throws IOException {
        if (User.isHBaseSecurityEnabled(job)) {
            try {
                User.getCurrent().obtainAuthTokenForJob(job);
            } catch (InterruptedException e) {
                throw new IOException("Error while obtaining hbase delegation token", e);
            }
        }
    }

}
