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

import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.regression.core.bundle.Bundle;
import org.apache.falcon.regression.core.helpers.ColoHelper;
import org.apache.falcon.regression.core.supportClasses.Brother;
import org.apache.falcon.regression.core.util.AssertUtil;
import org.apache.falcon.regression.core.util.BundleUtil;
import org.apache.falcon.regression.core.util.OSUtil;
import org.apache.falcon.regression.core.util.TimeUtil;
import org.apache.falcon.regression.core.util.Util;
import org.apache.falcon.regression.core.util.Util.URLS;
import org.apache.falcon.regression.testHelper.BaseTestClass;
import org.apache.log4j.Logger;
import org.apache.oozie.client.Job;
import org.apache.oozie.client.OozieClient;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.io.IOException;
import java.lang.reflect.Method;


@Test(groups = "embedded")
public class PrismConcurrentRequestTest extends BaseTestClass {

    ColoHelper cluster = servers.get(0);
    OozieClient clusterOC = serverOC.get(0);
    private ThreadGroup brotherGrimm = null;
    private Brother brothers[] = null;
    String aggregateWorkflowDir = baseHDFSDir + "/PrismConcurrentRequest/aggregator";
    private static final Logger logger = Logger.getLogger(PrismConcurrentRequestTest.class);
    String feed;

    @BeforeClass(alwaysRun = true)
    public void uploadWorkflow() throws Exception {
        uploadDirToClusters(aggregateWorkflowDir, OSUtil.RESOURCES_OOZIE);
    }

    @BeforeMethod(alwaysRun = true)
    public void setup(Method method) throws Exception {
        logger.info("test name: " + method.getName());
        bundles[0] = BundleUtil.readELBundle(baseAppHDFSDir, this.getClass().getSimpleName());
        bundles[0].generateUniqueBundle();
        bundles[0] = new Bundle(bundles[0], cluster);
        bundles[0].setProcessWorkflow(aggregateWorkflowDir);
        brotherGrimm = new ThreadGroup("mixed");
        brothers = new Brother[10];
        feed = bundles[0].getDataSets().get(0);
    }

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

    /**
     *  Submits the same feed concurrently in 10 threads. Checks that all attempts succeeded.
     */
    @Test(groups = {"multiCluster"})
    public void submitFeedParallel() throws Exception {
        prism.getClusterHelper().submitEntity(bundles[0].getClusters().get(0));
        for (int i = 1; i <= brothers.length; i++) {
            brothers[i - 1] =
                new Brother("brother" + i, "submit", EntityType.FEED, brotherGrimm, bundles[0],
                    prism, URLS.SUBMIT_URL);
        }
        for (Brother brother : brothers) {
            brother.start();
        }
        for (Brother brother : brothers) {
            brother.join();
        }
        for (Brother brother : brothers) {
            logger.info(brother.getName() + " output: \n" +
                Util.prettyPrintXml(brother.getOutput().getMessage()));
            AssertUtil.assertSucceeded(brother.getOutput());
        }
    }

    /**
     *  Submits the same process concurrently in 10 threads. Checks that all attempts succeeded.
     */
    @Test(groups = {"multiCluster"})
    public void submitProcessParallel() throws Exception {
        prism.getClusterHelper().submitEntity(bundles[0].getClusters().get(0));
        prism.getFeedHelper().submitEntity(bundles[0].getDataSets().get(0));
        prism.getFeedHelper().submitEntity(bundles[0].getDataSets().get(1));
        for (int i = 1; i <= brothers.length; i++) {
            brothers[i - 1] =
                new Brother("brother" + i, "submit", EntityType.PROCESS, brotherGrimm, bundles[0],
                    prism, URLS.SUBMIT_URL);
        }
        for (Brother brother : brothers) {
            brother.start();
        }
        for (Brother brother : brothers) {
            brother.join();
        }
        for (Brother brother : brothers) {
            logger.info(brother.getName() + " output: \n" +
                Util.prettyPrintXml(brother.getOutput().getMessage()));
            AssertUtil.assertSucceeded(brother.getOutput());
        }
    }

    /**
     *  Tries to delete same process concurrently in 10 threads. All attempts should succeed.
     */
    @Test(groups = {"multiCluster"})
    public void deleteProcessParallel() throws Exception {
        bundles[0].submitBundle(prism);
        for (int i = 1; i <= brothers.length; i++) {
            brothers[i - 1] =
                new Brother("brother" + i, "delete", EntityType.PROCESS, brotherGrimm, bundles[0],
                    prism, URLS.DELETE_URL);
        }
        for (Brother brother : brothers) {
            brother.start();
        }
        for (Brother brother : brothers) {
            brother.join();
        }
        for (Brother brother : brothers) {
            logger.info(brother.getName() + " output: \n" +
                Util.prettyPrintXml(brother.getOutput().getMessage()));
            AssertUtil.assertSucceeded(brother.getOutput());
        }
    }

    /**
     *  Submits all required stuff. Tries to schedule the same process concurrently in 10 threads.
     *  All attempts should succeed.
     */
    @Test(groups = {"multiCluster"})
    public void scheduleProcessParallel() throws Exception {
        bundles[0].submitBundle(prism);
        for (int i = 1; i <= brothers.length; i++) {
            brothers[i - 1] =
                new Brother("brother" + i, "schedule", EntityType.PROCESS, brotherGrimm,
                    bundles[0], prism, URLS.SCHEDULE_URL);
        }
        for (Brother brother : brothers) {
            brother.start();
        }
        for (Brother brother : brothers) {
            brother.join();
        }
        for (Brother brother : brothers) {
            logger.info(brother.getName() + " output: \n" +
                Util.prettyPrintXml(brother.getOutput().getMessage()));
            AssertUtil.assertSucceeded(brother.getOutput());
        }
    }

    /**
     *  Schedules and suspends feed. Tries to resume it concurrently in 2 threads and then
     *  suspend it again on other 2 threads. All actions should succeed.
     */
    @Test(groups = {"multiCluster"})
    public void resumeAndSuspendFeedParallel() throws Exception {
        brothers = new Brother[4];
        prism.getClusterHelper().submitEntity(bundles[0].getClusters().get(0));
        prism.getFeedHelper().submitEntity(feed);
        AssertUtil.assertSucceeded(prism.getFeedHelper().schedule(feed));
        AssertUtil.checkStatus(clusterOC, EntityType.FEED, feed, Job.Status.RUNNING);
        prism.getFeedHelper().suspend(feed);
        AssertUtil.checkStatus(clusterOC, EntityType.FEED, feed, Job.Status.SUSPENDED);
        for (int i = 1; i <= 2; i++) {
            brothers[i - 1] =
                new Brother("brother" + i, "resume", EntityType.FEED, brotherGrimm, bundles[0],
                    prism, URLS.RESUME_URL);
        }
        for (int i = 3; i <= 4; i++) {
            brothers[i - 1] =
                new Brother("brother" + i, "suspend", EntityType.FEED, brotherGrimm, bundles[0],
                    prism, URLS.SUSPEND_URL);
        }
        for (Brother brother : brothers) {
            brother.start();
        }
        for (Brother brother : brothers) {
            brother.join();
        }
        for (Brother brother : brothers) {
            logger.info(brother.getName() + " output: \n" +
                Util.prettyPrintXml(brother.getOutput().getMessage()));
            AssertUtil.assertSucceeded(brother.getOutput());
        }
    }

    /**
     *  Schedules and suspends feed. Then tries to resume it concurrently in 10 threads. All
     *  attempts should succeed.
     */
    @Test(groups = {"multiCluster"})
    public void resumeFeedParallel() throws Exception {
        final double delay = 15;
        prism.getClusterHelper().submitEntity(bundles[0].getClusters().get(0));
        prism.getFeedHelper().submitEntity(feed);
        AssertUtil.assertSucceeded(prism.getFeedHelper().schedule(feed));
        TimeUtil.sleepSeconds(delay);
        AssertUtil.checkStatus(clusterOC, EntityType.FEED, feed, Job.Status.RUNNING);
        prism.getFeedHelper().resume(feed);
        TimeUtil.sleepSeconds(delay);
        AssertUtil.checkStatus(clusterOC, EntityType.FEED, feed, Job.Status.RUNNING);
        prism.getFeedHelper().suspend(feed);
        TimeUtil.sleepSeconds(delay);
        AssertUtil.checkStatus(clusterOC, EntityType.FEED, feed, Job.Status.SUSPENDED);
        for (int i = 1; i <= brothers.length; i++) {
            brothers[i - 1] =
                new Brother("brother" + i, "resume", EntityType.FEED, brotherGrimm, bundles[0],
                    prism, URLS.RESUME_URL);
        }
        for (Brother brother : brothers) {
            brother.start();
        }
        for (Brother brother : brothers) {
            brother.join();
        }
        for (Brother brother : brothers) {
            logger.info(brother.getName() + " output: \n" +
                Util.prettyPrintXml(brother.getOutput().getMessage()));
            AssertUtil.assertSucceeded(brother.getOutput());
        }
    }

    /**
     *  Tries to submit cluster concurrently in 10 threads. Checks that all attempts succeeded.
     */
    @Test(groups = {"multiCluster"})
    public void submitClusterParallel() throws Exception {
        for (int i = 1; i <= brothers.length; i++) {
            brothers[i - 1] =
                new Brother("brother" + i, "submit", EntityType.CLUSTER, brotherGrimm, bundles[0],
                    prism, URLS.SUBMIT_URL);
        }
        for (Brother brother : brothers) {
            brother.start();
        }
        for (Brother brother : brothers) {
            brother.join();
        }
        for (Brother brother : brothers) {
            logger.info(brother.getName() + " output: \n" +
                Util.prettyPrintXml(brother.getOutput().getMessage()));
            AssertUtil.assertSucceeded(brother.getOutput());
        }
    }

    @AfterClass(alwaysRun = true)
    public void tearDownClass() throws IOException {
        cleanTestDirs();
    }
}
