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

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

import org.apache.hadoop.hive.cli.CliSessionState;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.ql.CommandNeedRetryException;
import org.apache.hadoop.hive.ql.Driver;
import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.hcatalog.MiniCluster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Helper class for Other Data Testers
 */
public class HCatDataCheckUtil {

    private static final Logger LOG = LoggerFactory.getLogger(HCatDataCheckUtil.class);

    public static Driver instantiateDriver(MiniCluster cluster) {
        HiveConf hiveConf = new HiveConf(HCatDataCheckUtil.class);
        for (Entry e : cluster.getProperties().entrySet()) {
            hiveConf.set(e.getKey().toString(), e.getValue().toString());
        }
        hiveConf.set(HiveConf.ConfVars.PREEXECHOOKS.varname, "");
        hiveConf.set(HiveConf.ConfVars.POSTEXECHOOKS.varname, "");
        hiveConf.set(HiveConf.ConfVars.HIVE_SUPPORT_CONCURRENCY.varname, "false");

        LOG.debug("Hive conf : {}", hiveConf.getAllProperties());
        Driver driver = new Driver(hiveConf);
        SessionState.start(new CliSessionState(hiveConf));
        return driver;
    }

    public static void generateDataFile(MiniCluster cluster, String fileName) throws IOException {
        MiniCluster.deleteFile(cluster, fileName);
        String[] input = new String[50];
        for (int i = 0; i < 50; i++) {
            input[i] = (i % 5) + "\t" + i + "\t" + "_S" + i + "S_";
        }
        MiniCluster.createInputFile(cluster, fileName, input);
    }

    public static void createTable(Driver driver, String tableName, String createTableArgs)
        throws CommandNeedRetryException, IOException {
        String createTable = "create table " + tableName + createTableArgs;
        int retCode = driver.run(createTable).getResponseCode();
        if (retCode != 0) {
            throw new IOException("Failed to create table. [" + createTable + "], return code from hive driver : [" + retCode + "]");
        }
    }

    public static void dropTable(Driver driver, String tablename) throws IOException, CommandNeedRetryException {
        driver.run("drop table if exists " + tablename);
    }

    public static ArrayList<String> formattedRun(Driver driver, String name, String selectCmd)
        throws CommandNeedRetryException, IOException {
        driver.run(selectCmd);
        ArrayList<String> src_values = new ArrayList<String>();
        driver.getResults(src_values);
        LOG.info("{} : {}", name, src_values);
        return src_values;
    }


    public static boolean recordsEqual(HCatRecord first, HCatRecord second) {
        return (compareRecords(first, second) == 0);
    }

    public static int compareRecords(HCatRecord first, HCatRecord second) {
        return compareRecordContents(first.getAll(), second.getAll());
    }

    public static int compareRecordContents(List<Object> first, List<Object> second) {
        int mySz = first.size();
        int urSz = second.size();
        if (mySz != urSz) {
            return mySz - urSz;
        } else {
            for (int i = 0; i < first.size(); i++) {
                int c = DataType.compare(first.get(i), second.get(i));
                if (c != 0) {
                    return c;
                }
            }
            return 0;
        }
    }


}
