/**
 * 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);

  }
 }
