/**
 * 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.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import junit.framework.Assert;

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.processors.CommandProcessorResponse;
import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.pig.ExecType;
import org.apache.pig.PigServer;
import org.apache.pig.backend.executionengine.ExecException;
import org.apache.pig.backend.executionengine.ExecJob;
import org.apache.pig.data.BagFactory;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
import org.apache.pig.impl.logicalLayer.FrontendException;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.impl.logicalLayer.schema.Schema.FieldSchema;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestHCatLoaderComplexSchema {

    //private static MiniCluster cluster = MiniCluster.buildCluster();
    private static Driver driver;
    //private static Properties props;
    private static final Logger LOG = LoggerFactory.getLogger(TestHCatLoaderComplexSchema.class);

    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') ";
        LOG.info("Creating table:\n {}", createTable);
        CommandProcessorResponse result = driver.run(createTable);
        int retCode = result.getResponseCode();
        if (retCode != 0) {
            throw new IOException("Failed to create table. [" + createTable + "], return code from hive driver : [" + retCode + " " + result.getErrorMessage() + "]");
        }
    }

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

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {

        HiveConf hiveConf = new HiveConf(TestHCatLoaderComplexSchema.class);
        hiveConf.set(HiveConf.ConfVars.PREEXECHOOKS.varname, "");
        hiveConf.set(HiveConf.ConfVars.POSTEXECHOOKS.varname, "");
        hiveConf.set(HiveConf.ConfVars.HIVE_SUPPORT_CONCURRENCY.varname, "false");
        driver = new Driver(hiveConf);
        SessionState.start(new CliSessionState(hiveConf));
        //props = new Properties();
        //props.setProperty("fs.default.name", cluster.getProperties().getProperty("fs.default.name"));

    }

    private static final TupleFactory tf = TupleFactory.getInstance();
    private static final BagFactory bf = BagFactory.getInstance();

    private Tuple t(Object... objects) {
        return tf.newTuple(Arrays.asList(objects));
    }

    private DataBag b(Tuple... objects) {
        return bf.newDefaultBag(Arrays.asList(objects));
    }

    /**
     * artificially complex nested schema to test nested schema conversion
     * @throws Exception
     */
    @Test
    public void testSyntheticComplexSchema() throws Exception {
        String pigSchema =
                "a: " +
                "(" +
                "aa: chararray, " +
                "ab: long, " +
                "ac: map[], " +
                "ad: { t: (ada: long) }, " +
                "ae: { t: (aea:long, aeb: ( aeba: chararray, aebb: long)) }," +
                "af: (afa: chararray, afb: long) " +
                ")," +
                "b: chararray, " +
                "c: long, " +
                "d:  { t: (da:long, db: ( dba: chararray, dbb: long), dc: { t: (dca: long) } ) } ";

        // with extra structs
        String tableSchema =
            "a struct<" +
                "aa: string, " +
                "ab: bigint, " +
                "ac: map<string, string>, " +
                "ad: array<struct<ada:bigint>>, " +
                "ae: array<struct<aea:bigint, aeb: struct<aeba: string, aebb: bigint>>>," +
                "af: struct<afa: string, afb: bigint> " +
                ">, " +
                "b string, " +
                "c bigint, " +
                "d array<struct<da: bigint, db: struct<dba:string, dbb:bigint>, dc: array<struct<dca: bigint>>>>";

        // without extra structs
        String tableSchema2 =
            "a struct<" +
                "aa: string, " +
                "ab: bigint, " +
                "ac: map<string, string>, " +
                "ad: array<bigint>, " +
                "ae: array<struct<aea:bigint, aeb: struct<aeba: string, aebb: bigint>>>," +
                "af: struct<afa: string, afb: bigint> " +
                ">, " +
                "b string, " +
                "c bigint, " +
                "d array<struct<da: bigint, db: struct<dba:string, dbb:bigint>, dc: array<bigint>>>";

        List<Tuple> data = new ArrayList<Tuple>();
        for (int i = 0; i < 10; i++) {
            Tuple t = t(
                t(
                    "aa test",
                    2l,
                    new HashMap<String, String>() {
                        {
                            put("ac test1", "test 1");
                            put("ac test2", "test 2");
                        }
                    },
                    b(t(3l), t(4l)),
                    b(t(5l, t("aeba test", 6l))),
                    t("afa test", 7l)
                ),
                "b test",
                (long) i,
                b(t(8l, t("dba test", 9l), b(t(10l)))));

            data.add(t);
        }
        verifyWriteRead("testSyntheticComplexSchema", pigSchema, tableSchema, data, true);
        verifyWriteRead("testSyntheticComplexSchema", pigSchema, tableSchema, data, false);
        verifyWriteRead("testSyntheticComplexSchema2", pigSchema, tableSchema2, data, true);
        verifyWriteRead("testSyntheticComplexSchema2", pigSchema, tableSchema2, data, false);

    }

    private void verifyWriteRead(String tablename, String pigSchema, String tableSchema, List<Tuple> data, boolean provideSchemaToStorer)
        throws IOException, CommandNeedRetryException, ExecException, FrontendException {
        MockLoader.setData(tablename + "Input", data);
        try {
            createTable(tablename, tableSchema);
            PigServer server = new PigServer(ExecType.LOCAL);
            server.setBatchOn();
            server.registerQuery("A = load '" + tablename + "Input' using org.apache.hcatalog.pig.MockLoader() AS (" + pigSchema + ");");
            Schema dumpedASchema = server.dumpSchema("A");
            server.registerQuery("STORE A into '" + tablename + "' using org.apache.hcatalog.pig.HCatStorer("
                + (provideSchemaToStorer ? "'', '" + pigSchema + "'" : "")
                + ");");

            ExecJob execJob = server.executeBatch().get(0);
            if (!execJob.getStatistics().isSuccessful()) {
                throw new RuntimeException("Import failed", execJob.getException());
            }
            // test that schema was loaded correctly
            server.registerQuery("X = load '" + tablename + "' using org.apache.hcatalog.pig.HCatLoader();");
            server.dumpSchema("X");
            Iterator<Tuple> it = server.openIterator("X");
            int i = 0;
            while (it.hasNext()) {
                Tuple input = data.get(i++);
                Tuple output = it.next();
                Assert.assertEquals(input.toString(), output.toString());
                LOG.info("tuple : {} ", output);
            }
            Schema dumpedXSchema = server.dumpSchema("X");

            Assert.assertEquals(
                "expected " + dumpedASchema + " but was " + dumpedXSchema + " (ignoring field names)",
                "",
                compareIgnoreFiledNames(dumpedASchema, dumpedXSchema));

        } finally {
            dropTable(tablename);
        }
    }

    private String compareIgnoreFiledNames(Schema expected, Schema got) throws FrontendException {
        if (expected == null || got == null) {
            if (expected == got) {
                return "";
            } else {
                return "\nexpected " + expected + " got " + got;
            }
        }
        if (expected.size() != got.size()) {
            return "\nsize expected " + expected.size() + " (" + expected + ") got " + got.size() + " (" + got + ")";
        }
        String message = "";
        for (int i = 0; i < expected.size(); i++) {
            FieldSchema expectedField = expected.getField(i);
            FieldSchema gotField = got.getField(i);
            if (expectedField.type != gotField.type) {
                message += "\ntype expected " + expectedField.type + " (" + expectedField + ") got " + gotField.type + " (" + gotField + ")";
            } else {
                message += compareIgnoreFiledNames(expectedField.schema, gotField.schema);
            }
        }
        return message;
    }

    /**
     * tests that unnecessary tuples are drop while converting schema
     * (Pig requires Tuples in Bags)
     * @throws Exception
     */
    @Test
    public void testTupleInBagInTupleInBag() throws Exception {
        String pigSchema = "a: { b : ( c: { d: (i : long) } ) }";

        String tableSchema = "a array< array< bigint > >";

        List<Tuple> data = new ArrayList<Tuple>();
        data.add(t(b(t(b(t(100l), t(101l))), t(b(t(110l))))));
        data.add(t(b(t(b(t(200l))), t(b(t(210l))), t(b(t(220l))))));
        data.add(t(b(t(b(t(300l), t(301l))))));
        data.add(t(b(t(b(t(400l))), t(b(t(410l), t(411l), t(412l))))));


        verifyWriteRead("TupleInBagInTupleInBag1", pigSchema, tableSchema, data, true);
        verifyWriteRead("TupleInBagInTupleInBag2", pigSchema, tableSchema, data, false);

        // test that we don't drop the unnecessary tuple if the table has the corresponding Struct
        String tableSchema2 = "a array< struct< c: array< struct< i: bigint > > > >";

        verifyWriteRead("TupleInBagInTupleInBag3", pigSchema, tableSchema2, data, true);
        verifyWriteRead("TupleInBagInTupleInBag4", pigSchema, tableSchema2, data, false);

    }

    @Test
    public void testMapWithComplexData() throws Exception {
        String pigSchema = "a: long, b: map[]";
        String tableSchema = "a bigint, b map<string, struct<aa:bigint, ab:string>>";

        List<Tuple> data = new ArrayList<Tuple>();
        for (int i = 0; i < 10; i++) {
            Tuple t = t(
                (long) i,
                new HashMap<String, Object>() {
                    {
                        put("b test 1", t(1l, "test 1"));
                        put("b test 2", t(2l, "test 2"));
                    }
                });

            data.add(t);
        }
        verifyWriteRead("testMapWithComplexData", pigSchema, tableSchema, data, true);
        verifyWriteRead("testMapWithComplexData2", pigSchema, tableSchema, data, false);

    }
}
