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

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import junit.framework.TestCase;

import org.apache.hadoop.fs.FileUtil;
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.hadoop.mapreduce.Job;
import org.apache.hcatalog.HcatTestUtils;
import org.apache.hcatalog.common.HCatConstants;
import org.apache.hcatalog.data.Pair;
import org.apache.pig.ExecType;
import org.apache.pig.PigServer;
import org.apache.pig.ResourceStatistics;
import org.apache.pig.data.DataType;
import org.apache.pig.data.Tuple;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.impl.logicalLayer.schema.Schema.FieldSchema;

public class TestHCatLoader extends TestCase {
    private static final String TEST_DATA_DIR = System.getProperty("user.dir") +
        "/build/test/data/" + TestHCatLoader.class.getCanonicalName();
    private static final String TEST_WAREHOUSE_DIR = TEST_DATA_DIR + "/warehouse";
    private static final String BASIC_FILE_NAME = TEST_DATA_DIR + "/basic.input.data";
    private static final String COMPLEX_FILE_NAME = TEST_DATA_DIR + "/complex.input.data";

    private static final String BASIC_TABLE = "junit_unparted_basic";
    private static final String COMPLEX_TABLE = "junit_unparted_complex";
    private static final String PARTITIONED_TABLE = "junit_parted_basic";
    private static final String SPECIFIC_SIZE_TABLE = "junit_specific_size";
    private static Driver driver;

    private static int guardTestCount = 6; // ugh, instantiate using introspection in guardedSetupBeforeClass
    private static boolean setupHasRun = false;

    private static Map<Integer, Pair<Integer, String>> basicInputData;

    private void dropTable(String tablename) throws IOException, CommandNeedRetryException {
        driver.run("drop table " + tablename);
    }

    private void createTable(String tablename, String schema, String partitionedBy) throws IOException, CommandNeedRetryException {
        String createTable;
        createTable = "create table " + tablename + "(" + schema + ") ";
        if ((partitionedBy != null) && (!partitionedBy.trim().isEmpty())) {
            createTable = createTable + "partitioned by (" + partitionedBy + ") ";
        }
        createTable = createTable + "stored as RCFILE tblproperties('hcat.isd'='org.apache.hcatalog.rcfile.RCFileInputDriver'," +
            "'hcat.osd'='org.apache.hcatalog.rcfile.RCFileOutputDriver') ";
        int retCode = driver.run(createTable).getResponseCode();
        if (retCode != 0) {
            throw new IOException("Failed to create table. [" + createTable + "], return code from hive driver : [" + retCode + "]");
        }
    }

    private void createTable(String tablename, String schema) throws IOException, CommandNeedRetryException {
        createTable(tablename, schema, null);
    }

    protected void guardedSetUpBeforeClass() throws Exception {
        if (!setupHasRun) {
            setupHasRun = true;
        } else {
            return;
        }

        File f = new File(TEST_WAREHOUSE_DIR);
        if (f.exists()) {
            FileUtil.fullyDelete(f);
        }
        new File(TEST_WAREHOUSE_DIR).mkdirs();

        HiveConf hiveConf = new HiveConf(this.getClass());
        hiveConf.set(HiveConf.ConfVars.PREEXECHOOKS.varname, "");
        hiveConf.set(HiveConf.ConfVars.POSTEXECHOOKS.varname, "");
        hiveConf.set(HiveConf.ConfVars.HIVE_SUPPORT_CONCURRENCY.varname, "false");
        hiveConf.set(HiveConf.ConfVars.METASTOREWAREHOUSE.varname, TEST_WAREHOUSE_DIR);
        driver = new Driver(hiveConf);
        SessionState.start(new CliSessionState(hiveConf));

        cleanup();

        createTable(BASIC_TABLE, "a int, b string");
        createTable(COMPLEX_TABLE,
            "name string, studentid int, "
                + "contact struct<phno:string,email:string>, "
                + "currently_registered_courses array<string>, "
                + "current_grades map<string,string>, "
                + "phnos array<struct<phno:string,type:string>>");

        createTable(PARTITIONED_TABLE, "a int, b string", "bkt string");
        createTable(SPECIFIC_SIZE_TABLE, "a int, b string");

        int LOOP_SIZE = 3;
        String[] input = new String[LOOP_SIZE * LOOP_SIZE];
        basicInputData = new HashMap<Integer, Pair<Integer, String>>();
        int k = 0;
        for (int i = 1; i <= LOOP_SIZE; i++) {
            String si = i + "";
            for (int j = 1; j <= LOOP_SIZE; j++) {
                String sj = "S" + j + "S";
                input[k] = si + "\t" + sj;
                basicInputData.put(k, new Pair<Integer, String>(i, sj));
                k++;
            }
        }
        HcatTestUtils.createTestDataFile(BASIC_FILE_NAME, input);
        HcatTestUtils.createTestDataFile(COMPLEX_FILE_NAME,
            new String[]{
                //"Henry Jekyll\t42\t(415-253-6367,hjekyll@contemporary.edu.uk)\t{(PHARMACOLOGY),(PSYCHIATRY)},[PHARMACOLOGY#A-,PSYCHIATRY#B+],{(415-253-6367,cell),(408-253-6367,landline)}",
                //"Edward Hyde\t1337\t(415-253-6367,anonymous@b44chan.org)\t{(CREATIVE_WRITING),(COPYRIGHT_LAW)},[CREATIVE_WRITING#A+,COPYRIGHT_LAW#D],{(415-253-6367,cell),(408-253-6367,landline)}",
            }
        );

        PigServer server = new PigServer(ExecType.LOCAL);
        server.setBatchOn();
        server.registerQuery("A = load '" + BASIC_FILE_NAME + "' as (a:int, b:chararray);");

        server.registerQuery("store A into '" + BASIC_TABLE + "' using org.apache.hcatalog.pig.HCatStorer();");
        server.registerQuery("store A into '" + SPECIFIC_SIZE_TABLE + "' using org.apache.hcatalog.pig.HCatStorer();");
        server.registerQuery("B = foreach A generate a,b;");
        server.registerQuery("B2 = filter B by a < 2;");
        server.registerQuery("store B2 into '" + PARTITIONED_TABLE + "' using org.apache.hcatalog.pig.HCatStorer('bkt=0');");

        server.registerQuery("C = foreach A generate a,b;");
        server.registerQuery("C2 = filter C by a >= 2;");
        server.registerQuery("store C2 into '" + PARTITIONED_TABLE + "' using org.apache.hcatalog.pig.HCatStorer('bkt=1');");

        server.registerQuery("D = load '" + COMPLEX_FILE_NAME + "' as (name:chararray, studentid:int, contact:tuple(phno:chararray,email:chararray), currently_registered_courses:bag{innertup:tuple(course:chararray)}, current_grades:map[ ] , phnos :bag{innertup:tuple(phno:chararray,type:chararray)});");
        server.registerQuery("store D into '" + COMPLEX_TABLE + "' using org.apache.hcatalog.pig.HCatStorer();");
        server.executeBatch();

    }

    private void cleanup() throws IOException, CommandNeedRetryException {
        dropTable(BASIC_TABLE);
        dropTable(COMPLEX_TABLE);
        dropTable(PARTITIONED_TABLE);
        dropTable(SPECIFIC_SIZE_TABLE);
    }

    protected void guardedTearDownAfterClass() throws Exception {
        guardTestCount--;
        if (guardTestCount > 0) {
            return;
        }
        cleanup();
    }

    @Override
    protected void setUp() throws Exception {
        guardedSetUpBeforeClass();
    }

    @Override
    protected void tearDown() throws Exception {
        guardedTearDownAfterClass();
    }

    public void testSchemaLoadBasic() throws IOException {

        PigServer server = new PigServer(ExecType.LOCAL);

        // test that schema was loaded correctly
        server.registerQuery("X = load '" + BASIC_TABLE + "' using org.apache.hcatalog.pig.HCatLoader();");
        Schema dumpedXSchema = server.dumpSchema("X");
        List<FieldSchema> Xfields = dumpedXSchema.getFields();
        assertEquals(2, Xfields.size());
        assertTrue(Xfields.get(0).alias.equalsIgnoreCase("a"));
        assertTrue(Xfields.get(0).type == DataType.INTEGER);
        assertTrue(Xfields.get(1).alias.equalsIgnoreCase("b"));
        assertTrue(Xfields.get(1).type == DataType.CHARARRAY);

    }

    public void testReadDataBasic() throws IOException {
        PigServer server = new PigServer(ExecType.LOCAL);

        server.registerQuery("X = load '" + BASIC_TABLE + "' using org.apache.hcatalog.pig.HCatLoader();");
        Iterator<Tuple> XIter = server.openIterator("X");
        int numTuplesRead = 0;
        while (XIter.hasNext()) {
            Tuple t = XIter.next();
            assertEquals(2, t.size());
            assertTrue(t.get(0).getClass() == Integer.class);
            assertTrue(t.get(1).getClass() == String.class);
            assertEquals(t.get(0), basicInputData.get(numTuplesRead).first);
            assertEquals(t.get(1), basicInputData.get(numTuplesRead).second);
            numTuplesRead++;
        }
        assertEquals(basicInputData.size(), numTuplesRead);
    }

    public void testSchemaLoadComplex() throws IOException {

        PigServer server = new PigServer(ExecType.LOCAL);

        // test that schema was loaded correctly
        server.registerQuery("K = load '" + COMPLEX_TABLE + "' using org.apache.hcatalog.pig.HCatLoader();");
        Schema dumpedKSchema = server.dumpSchema("K");
        List<FieldSchema> Kfields = dumpedKSchema.getFields();
        assertEquals(6, Kfields.size());

        assertEquals(DataType.CHARARRAY, Kfields.get(0).type);
        assertEquals("name", Kfields.get(0).alias.toLowerCase());

        assertEquals(DataType.INTEGER, Kfields.get(1).type);
        assertEquals("studentid", Kfields.get(1).alias.toLowerCase());

        assertEquals(DataType.TUPLE, Kfields.get(2).type);
        assertEquals("contact", Kfields.get(2).alias.toLowerCase());
        {
            assertNotNull(Kfields.get(2).schema);
            assertTrue(Kfields.get(2).schema.getFields().size() == 2);
            assertTrue(Kfields.get(2).schema.getFields().get(0).type == DataType.CHARARRAY);
            assertTrue(Kfields.get(2).schema.getFields().get(0).alias.equalsIgnoreCase("phno"));
            assertTrue(Kfields.get(2).schema.getFields().get(1).type == DataType.CHARARRAY);
            assertTrue(Kfields.get(2).schema.getFields().get(1).alias.equalsIgnoreCase("email"));
        }
        assertEquals(DataType.BAG, Kfields.get(3).type);
        assertEquals("currently_registered_courses", Kfields.get(3).alias.toLowerCase());
        {
            assertNotNull(Kfields.get(3).schema);
            assertEquals(1, Kfields.get(3).schema.getFields().size());
            assertEquals(DataType.TUPLE, Kfields.get(3).schema.getFields().get(0).type);
            assertNotNull(Kfields.get(3).schema.getFields().get(0).schema);
            assertEquals(1, Kfields.get(3).schema.getFields().get(0).schema.getFields().size());
            assertEquals(DataType.CHARARRAY, Kfields.get(3).schema.getFields().get(0).schema.getFields().get(0).type);
            // assertEquals("course",Kfields.get(3).schema.getFields().get(0).schema.getFields().get(0).alias.toLowerCase());
            // commented out, because the name becomes "innerfield" by default - we call it "course" in pig,
            // but in the metadata, it'd be anonymous, so this would be autogenerated, which is fine
        }
        assertEquals(DataType.MAP, Kfields.get(4).type);
        assertEquals("current_grades", Kfields.get(4).alias.toLowerCase());
        assertEquals(DataType.BAG, Kfields.get(5).type);
        assertEquals("phnos", Kfields.get(5).alias.toLowerCase());
        {
            assertNotNull(Kfields.get(5).schema);
            assertEquals(1, Kfields.get(5).schema.getFields().size());
            assertEquals(DataType.TUPLE, Kfields.get(5).schema.getFields().get(0).type);
            assertNotNull(Kfields.get(5).schema.getFields().get(0).schema);
            assertTrue(Kfields.get(5).schema.getFields().get(0).schema.getFields().size() == 2);
            assertEquals(DataType.CHARARRAY, Kfields.get(5).schema.getFields().get(0).schema.getFields().get(0).type);
            assertEquals("phno", Kfields.get(5).schema.getFields().get(0).schema.getFields().get(0).alias.toLowerCase());
            assertEquals(DataType.CHARARRAY, Kfields.get(5).schema.getFields().get(0).schema.getFields().get(1).type);
            assertEquals("type", Kfields.get(5).schema.getFields().get(0).schema.getFields().get(1).alias.toLowerCase());
        }

    }

    public void testReadPartitionedBasic() throws IOException, CommandNeedRetryException {
        PigServer server = new PigServer(ExecType.LOCAL);

        driver.run("select * from " + PARTITIONED_TABLE);
        ArrayList<String> valuesReadFromHiveDriver = new ArrayList<String>();
        driver.getResults(valuesReadFromHiveDriver);
        assertEquals(basicInputData.size(), valuesReadFromHiveDriver.size());

        server.registerQuery("W = load '" + PARTITIONED_TABLE + "' using org.apache.hcatalog.pig.HCatLoader();");
        Schema dumpedWSchema = server.dumpSchema("W");
        List<FieldSchema> Wfields = dumpedWSchema.getFields();
        assertEquals(3, Wfields.size());
        assertTrue(Wfields.get(0).alias.equalsIgnoreCase("a"));
        assertTrue(Wfields.get(0).type == DataType.INTEGER);
        assertTrue(Wfields.get(1).alias.equalsIgnoreCase("b"));
        assertTrue(Wfields.get(1).type == DataType.CHARARRAY);
        assertTrue(Wfields.get(2).alias.equalsIgnoreCase("bkt"));
        assertTrue(Wfields.get(2).type == DataType.CHARARRAY);

        Iterator<Tuple> WIter = server.openIterator("W");
        Collection<Pair<Integer, String>> valuesRead = new ArrayList<Pair<Integer, String>>();
        while (WIter.hasNext()) {
            Tuple t = WIter.next();
            assertTrue(t.size() == 3);
            assertTrue(t.get(0).getClass() == Integer.class);
            assertTrue(t.get(1).getClass() == String.class);
            assertTrue(t.get(2).getClass() == String.class);
            valuesRead.add(new Pair<Integer, String>((Integer) t.get(0), (String) t.get(1)));
            if ((Integer) t.get(0) < 2) {
                assertEquals("0", t.get(2));
            } else {
                assertEquals("1", t.get(2));
            }
        }
        assertEquals(valuesReadFromHiveDriver.size(), valuesRead.size());

        server.registerQuery("P1 = load '" + PARTITIONED_TABLE + "' using org.apache.hcatalog.pig.HCatLoader();");
        server.registerQuery("P1filter = filter P1 by bkt == '0';");
        Iterator<Tuple> P1Iter = server.openIterator("P1filter");
        int count1 = 0;
        while (P1Iter.hasNext()) {
            Tuple t = P1Iter.next();

            assertEquals("0", t.get(2));
            assertEquals(1, t.get(0));
            count1++;
        }
        assertEquals(3, count1);

        server.registerQuery("P2 = load '" + PARTITIONED_TABLE + "' using org.apache.hcatalog.pig.HCatLoader();");
        server.registerQuery("P2filter = filter P2 by bkt == '1';");
        Iterator<Tuple> P2Iter = server.openIterator("P2filter");
        int count2 = 0;
        while (P2Iter.hasNext()) {
            Tuple t = P2Iter.next();

            assertEquals("1", t.get(2));
            assertTrue(((Integer) t.get(0)) > 1);
            count2++;
        }
        assertEquals(6, count2);
    }

    public void testProjectionsBasic() throws IOException {

        PigServer server = new PigServer(ExecType.LOCAL);

        // projections are handled by using generate, not "as" on the Load

        server.registerQuery("Y1 = load '" + BASIC_TABLE + "' using org.apache.hcatalog.pig.HCatLoader();");
        server.registerQuery("Y2 = foreach Y1 generate a;");
        server.registerQuery("Y3 = foreach Y1 generate b,a;");
        Schema dumpedY2Schema = server.dumpSchema("Y2");
        Schema dumpedY3Schema = server.dumpSchema("Y3");
        List<FieldSchema> Y2fields = dumpedY2Schema.getFields();
        List<FieldSchema> Y3fields = dumpedY3Schema.getFields();
        assertEquals(1, Y2fields.size());
        assertEquals("a", Y2fields.get(0).alias.toLowerCase());
        assertEquals(DataType.INTEGER, Y2fields.get(0).type);
        assertEquals(2, Y3fields.size());
        assertEquals("b", Y3fields.get(0).alias.toLowerCase());
        assertEquals(DataType.CHARARRAY, Y3fields.get(0).type);
        assertEquals("a", Y3fields.get(1).alias.toLowerCase());
        assertEquals(DataType.INTEGER, Y3fields.get(1).type);

        int numTuplesRead = 0;
        Iterator<Tuple> Y2Iter = server.openIterator("Y2");
        while (Y2Iter.hasNext()) {
            Tuple t = Y2Iter.next();
            assertEquals(t.size(), 1);
            assertTrue(t.get(0).getClass() == Integer.class);
            assertEquals(t.get(0), basicInputData.get(numTuplesRead).first);
            numTuplesRead++;
        }
        numTuplesRead = 0;
        Iterator<Tuple> Y3Iter = server.openIterator("Y3");
        while (Y3Iter.hasNext()) {
            Tuple t = Y3Iter.next();
            assertEquals(t.size(), 2);
            assertTrue(t.get(0).getClass() == String.class);
            assertEquals(t.get(0), basicInputData.get(numTuplesRead).second);
            assertTrue(t.get(1).getClass() == Integer.class);
            assertEquals(t.get(1), basicInputData.get(numTuplesRead).first);
            numTuplesRead++;
        }
        assertEquals(basicInputData.size(), numTuplesRead);
    }

    public void testGetInputBytes() throws Exception {
        File file = new File(TEST_WAREHOUSE_DIR + "/" + SPECIFIC_SIZE_TABLE + "/part-m-00000");
        file.deleteOnExit();
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
        randomAccessFile.setLength(2L * 1024 * 1024 * 1024);

        Job job = new Job();
        HCatLoader hCatLoader = new HCatLoader();
        hCatLoader.setUDFContextSignature(this.getName());
        hCatLoader.setLocation(SPECIFIC_SIZE_TABLE, job);
        ResourceStatistics statistics = hCatLoader.getStatistics(file.getAbsolutePath(), job);
        assertEquals(2048, (long) statistics.getmBytes());
    }

    public void testConvertBooleanToInt() throws Exception {
        String tbl = "test_convert_boolean_to_int";
        String inputFileName = TEST_DATA_DIR + "/testConvertBooleanToInt/data.txt";
        File inputDataDir = new File(inputFileName).getParentFile();
        inputDataDir.mkdir();

        String[] lines = new String[]{"llama\t1", "alpaca\t0"};
        HcatTestUtils.createTestDataFile(inputFileName, lines);

        assertEquals(0, driver.run("drop table if exists " + tbl).getResponseCode());
        assertEquals(0, driver.run("create external table " + tbl +
            " (a string, b boolean) row format delimited fields terminated by '\t'" +
            " stored as textfile location 'file://" +
            inputDataDir.getAbsolutePath() + "'").getResponseCode());

        Properties properties = new Properties();
        properties.setProperty(HCatConstants.HCAT_DATA_CONVERT_BOOLEAN_TO_INTEGER, "true");
        PigServer server = new PigServer(ExecType.LOCAL, properties);
        server.registerQuery(
            "data = load 'test_convert_boolean_to_int' using org.apache.hcatalog.pig.HCatLoader();");
        Schema schema = server.dumpSchema("data");
        assertEquals(2, schema.getFields().size());

        assertEquals("a", schema.getField(0).alias);
        assertEquals(DataType.CHARARRAY, schema.getField(0).type);
        assertEquals("b", schema.getField(1).alias);
        assertEquals(DataType.INTEGER, schema.getField(1).type);

        Iterator<Tuple> iterator = server.openIterator("data");
        Tuple t = iterator.next();
        assertEquals("llama", t.get(0));
        // TODO: Figure out how to load a text file into Hive with boolean columns. This next assert
        // passes because data was loaded as integers, not because it was converted.
        assertEquals(1, t.get(1));
        t = iterator.next();
        assertEquals("alpaca", t.get(0));
        assertEquals(0, t.get(1));
        assertFalse(iterator.hasNext());
    }
}
