/**
 * 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.falcon.regression.hcat;

import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.entity.v0.Frequency;
import org.apache.falcon.entity.v0.cluster.Interfacetype;
import org.apache.falcon.entity.v0.feed.ActionType;
import org.apache.falcon.entity.v0.feed.ClusterType;
import org.apache.falcon.regression.Entities.FeedMerlin;
import org.apache.falcon.regression.core.bundle.Bundle;
import org.apache.falcon.regression.core.enumsAndConstants.FeedType;
import org.apache.falcon.regression.core.helpers.ColoHelper;
import org.apache.falcon.regression.core.response.ServiceResponse;
import org.apache.falcon.regression.core.util.AssertUtil;
import org.apache.falcon.regression.core.util.BundleUtil;
import org.apache.falcon.regression.core.util.HCatUtil;
import org.apache.falcon.regression.core.util.OSUtil;
import org.apache.falcon.regression.core.util.Util;
import org.apache.falcon.regression.core.util.InstanceUtil;
import org.apache.falcon.regression.core.util.XmlUtil;
import org.apache.falcon.regression.testHelper.BaseTestClass;
import org.apache.hive.hcatalog.api.HCatClient;
import org.apache.hive.hcatalog.api.HCatCreateTableDesc;
import org.apache.hive.hcatalog.common.HCatException;
import org.apache.hive.hcatalog.data.schema.HCatFieldSchema;
import org.apache.log4j.Logger;
import org.apache.oozie.client.Job;
import org.apache.oozie.client.OozieClient;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class HCatFeedOperationsTest extends BaseTestClass {

    ColoHelper cluster = servers.get(0);
    OozieClient clusterOC = serverOC.get(0);
    HCatClient clusterHC = cluster.getClusterHelper().getHCatClient();

    ColoHelper cluster2 = servers.get(1);
    OozieClient cluster2OC = serverOC.get(1);
    HCatClient cluster2HC = cluster2.getClusterHelper().getHCatClient();

    private String dbName = "default";
    private String tableName = "hcatFeedOperationsTest";
    private String randomTblName = "randomTable_HcatFeedOperationsTest";
    private String feed;
    private String aggregateWorkflowDir = baseHDFSDir + "/HCatFeedOperationsTest/aggregator";
    private static final Logger LOGGER = Logger.getLogger(HCatFeedOperationsTest.class);

    public void uploadWorkflow() throws Exception {
        uploadDirToClusters(aggregateWorkflowDir, OSUtil.RESOURCES_OOZIE);
    }

    @BeforeClass(alwaysRun = true)
    public void createTestData() throws Exception {
        //create an empty table for feed operations
        ArrayList<HCatFieldSchema> partitions = new ArrayList<HCatFieldSchema>();
        partitions.add(HCatUtil.getStringSchema("year", "yearPartition"));
        createEmptyTable(clusterHC, dbName, tableName, partitions);

        //A random table to test submission of replication feed when table doesn't exist on target
        createEmptyTable(clusterHC, dbName, randomTblName, partitions);

        //create empty table on target cluster
        createEmptyTable(cluster2HC, dbName, tableName, new ArrayList<HCatFieldSchema>());
    }

    @BeforeMethod(alwaysRun = true)
    public void setUp(Method method) throws Exception {
        LOGGER.info("test name: " + method.getName());
        Bundle bundle = BundleUtil.readHCatBundle(baseAppHDFSDir, this.getClass().getSimpleName());
        bundles[0] = new Bundle(bundle, cluster.getPrefix());
        bundles[0].generateUniqueBundle();
        bundles[0].setClusterInterface(Interfacetype.REGISTRY, cluster.getClusterHelper().getHCatEndpoint());


        bundles[1] = new Bundle(bundle, cluster2.getPrefix());
        bundles[1].generateUniqueBundle();
        bundles[1].setClusterInterface(Interfacetype.REGISTRY, cluster2.getClusterHelper().getHCatEndpoint());
    }

    @AfterMethod(alwaysRun = true)
    public void tearDown() throws HCatException {
        removeBundles();
    }

    @AfterClass(alwaysRun = true)
    public void tearDownClass() throws IOException {
        clusterHC.dropTable(dbName, tableName, true);
        clusterHC.dropTable(dbName, randomTblName, true);
        cluster2HC.dropTable(dbName, tableName, true);
        cleanTestDirs();
    }

    /**
     * Submit Hcat feed when Hcat table mentioned in table uri does not exist. Response should reflect failure.
     *
     * @throws Exception
     */
    @Test(groups = {"singleCluster"})
    public void submitFeedWhenTableDoesNotExist() throws Exception {
        Bundle.submitCluster(bundles[1]);
        feed = bundles[1].getInputFeedFromBundle();
        FeedMerlin feedObj = new FeedMerlin(feed);
        feedObj.setTableValue(dbName, randomTblName, FeedType.YEARLY.getHcatPathValue());
        ServiceResponse response = prism.getFeedHelper().submitEntity(feedObj.toString());
        AssertUtil.assertFailed(response);
    }

    /**
     * Submit Hcat feed when Hcat table mentioned in table uri exists. Delete that feed, and re-submit.
     * All responses should reflect success.
     *
     * @throws Exception
     */
    @Test(groups = {"singleCluster"})
    public void submitFeedPostDeletionWhenTableExists() throws Exception {
        Bundle.submitCluster(bundles[0]);
        feed = bundles[0].getInputFeedFromBundle();
        FeedMerlin feedObj = new FeedMerlin(feed);
        feedObj.setTableValue(dbName, tableName, FeedType.YEARLY.getHcatPathValue());
        ServiceResponse response = prism.getFeedHelper().submitEntity(feedObj.toString());
        AssertUtil.assertSucceeded(response);

        response = prism.getFeedHelper().delete(feedObj.toString());
        AssertUtil.assertSucceeded(response);

        response = prism.getFeedHelper().submitEntity(feedObj.toString());
        AssertUtil.assertSucceeded(response);
    }

    /**
     * Submit Hcat Replication feed when Hcat table mentioned in table uri does not exist on target. The response is
     * Partial, with successful with submit/schedule on source.
     *
     * @throws Exception
     */
    @Test
    public void submitAndScheduleReplicationFeedWhenTableDoesNotExistOnTarget() throws Exception {
        Bundle.submitCluster(bundles[0], bundles[1]);
        final String startDate = "2010-01-01T20:00Z";
        final String endDate = "2099-01-01T00:00Z";
        String tableUri = "catalog:" + dbName + ":" + randomTblName + "#year=${YEAR}";
        bundles[0].setInputFeedPeriodicity(1, Frequency.TimeUnit.hours);
        bundles[0].setInputFeedValidity(startDate, endDate);
        bundles[0].setInputFeedTableUri(tableUri);

        feed = bundles[0].getDataSets().get(0);
        // set cluster 2 as the target.
        feed = InstanceUtil.setFeedClusterWithTable(feed,
                XmlUtil.createValidity(startDate, endDate),
                XmlUtil.createRtention("months(9000)", ActionType.DELETE),
                Util.readEntityName(bundles[1].getClusters().get(0)), ClusterType.TARGET, null,
                tableUri);

        AssertUtil.assertPartial(prism.getFeedHelper().submitAndSchedule(feed));
    }

    /**
     * Submit Hcat Replication feed when Hcat table mentioned in table uri exists on both source and target. The response is
     * Psucceeded, and a replication co-rdinator should apear on target oozie. The test however does not ensure that
     * replication goes through.
     *
     * @throws Exception
     */
    @Test
    public void submitAndScheduleReplicationFeedWhenTableExistsOnSourceAndTarget() throws Exception {
        Bundle.submitCluster(bundles[0], bundles[1]);
        final String startDate = "2010-01-01T20:00Z";
        final String endDate = "2099-01-01T00:00Z";
        String tableUri = "catalog:" + dbName + ":" + tableName + "#year=${YEAR}";
        bundles[0].setInputFeedPeriodicity(1, Frequency.TimeUnit.hours);
        bundles[0].setInputFeedValidity(startDate, endDate);
        bundles[0].setInputFeedTableUri(tableUri);

        feed = bundles[0].getDataSets().get(0);
        // set cluster 2 as the target.
        feed = InstanceUtil.setFeedClusterWithTable(feed,
                XmlUtil.createValidity(startDate, endDate),
                XmlUtil.createRtention("months(9000)", ActionType.DELETE),
                Util.readEntityName(bundles[1].getClusters().get(0)), ClusterType.TARGET, null,
                tableUri);

        AssertUtil.assertSucceeded(prism.getFeedHelper().submitAndSchedule(feed));
        Assert.assertEquals(InstanceUtil
                .checkIfFeedCoordExist(cluster2.getFeedHelper(), Util.readEntityName(feed),
                        "REPLICATION"), 1);
        //This test doesn't wait for replication to succeed.
    }

    /**
     * Submit Hcat Replication feed. Suspend the feed, and check that feed was suspended on
     * both clusters. Now resume feed, and check that status is running on both clusters.
     * The test however does not ensure that replication goes through.
     *
     * @throws Exception
     */
    @Test
    public void suspendAndResumeReplicationFeed() throws Exception {

        submitAndScheduleReplicationFeedWhenTableExistsOnSourceAndTarget();

        AssertUtil.assertSucceeded(prism.getFeedHelper().suspend(feed));

        //check that feed suspended on both clusters
        AssertUtil.checkStatus(clusterOC, EntityType.FEED, feed, Job.Status.SUSPENDED);
        AssertUtil.checkStatus(cluster2OC, EntityType.FEED, feed, Job.Status.SUSPENDED);

        AssertUtil.assertSucceeded(prism.getFeedHelper().resume(feed));

        AssertUtil.checkStatus(clusterOC, EntityType.FEED, feed, Job.Status.RUNNING);
        AssertUtil.checkStatus(cluster2OC, EntityType.FEED, feed, Job.Status.RUNNING);
    }

    /**
     * Submit Hcat Replication feed. Delete the feed, and check that feed was deleted on
     * both clusters. The test however does not ensure that replication goes through.
     *
     * @throws Exception
     */
    @Test
    public void deleteReplicationFeed() throws Exception {
        submitAndScheduleReplicationFeedWhenTableExistsOnSourceAndTarget();

        AssertUtil.assertSucceeded(prism.getFeedHelper().delete(feed));
        AssertUtil.checkStatus(clusterOC, EntityType.FEED, feed, Job.Status.KILLED);
        AssertUtil.checkStatus(cluster2OC, EntityType.FEED, feed, Job.Status.KILLED);
    }


    public static void createEmptyTable(HCatClient cli, String dbName, String tabName, List<HCatFieldSchema> partitionCols) throws HCatException{

        ArrayList<HCatFieldSchema> cols = new ArrayList<HCatFieldSchema>();
        cols.add(HCatUtil.getStringSchema("id", "id comment"));
        HCatCreateTableDesc tableDesc = HCatCreateTableDesc
                .create(dbName, tabName, cols)
                .partCols(partitionCols)
                .fileFormat("textfile")
                .ifNotExists(true)
                .isTableExternal(true)
                .build();
        cli.createTable(tableDesc);
    }
}
