package alien4cloud.it.provider;

import java.util.Map;

import lombok.extern.slf4j.Slf4j;

import org.elasticsearch.common.collect.Maps;

import alien4cloud.it.application.ApplicationStepDefinitions;
import alien4cloud.it.application.deployment.ApplicationsDeploymentStepDefinitions;
import alien4cloud.it.application.deployment.DeploymentTopologyStepDefinitions;
import alien4cloud.it.common.CommonStepDefinitions;
import alien4cloud.model.application.Application;
import cucumber.api.java.en.When;

@Slf4j
public class LongRunStepDefinitions {

    private static final ApplicationsDeploymentStepDefinitions APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS = new ApplicationsDeploymentStepDefinitions();

    private static final DeploymentTopologyStepDefinitions DEPLOYMENT_TOPOLOGY = new DeploymentTopologyStepDefinitions();

    private static final CommonStepDefinitions COMMON_STEP_DEFINITIONS = new CommonStepDefinitions();

    private static final ApplicationStepDefinitions APPLICATION = new ApplicationStepDefinitions();

    @When("^I loop deploying/undeploying the app$")
    public void i_loop_deploying_undeploying_the_app() throws Throwable {
        int deployementCount = 0;
        while (true) {
            log.info("=============== Starting deployment #" + ++deployementCount);
            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.I_deploy_it();
            COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();
            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.The_application_s_deployment_should_succeed_after_minutes(15);
            log.info("=============== Ending deployment #" + deployementCount);
            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.I_undeploy_it();
            COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();
            log.info("=============== Ended deployment #" + deployementCount);
        }
    }

    @When("^I loop deploying/undeploying applications using the topology template \"(.*?)\" and location \"([^\"]*)\"/\"([^\"]*)\"$")
    public void i_loop_deploying_undeploying_the_app(String templateName, String orchestratorName, String locationName) throws Throwable {
        int deployementCount = 0;
        while (true) {
            String appName = "MyLongRunAppApp-" + deployementCount++;
            log.info("=============== creating app '" + appName + "'");
            APPLICATION.I_create_a_new_application_with_name_and_description_based_on_the_template_with_name(appName, "a description", templateName);
            DEPLOYMENT_TOPOLOGY.I_Set_a_unique_location_policy_to_for_all_nodes(orchestratorName, locationName);
            log.info("=============== deploying app '" + appName + "'");
            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.I_deploy_it();
            COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();
            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.The_application_s_deployment_should_succeed_after_minutes(15);
            log.info("=============== undeploying app '" + appName + "'");
            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.I_undeploy_it();
            COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();
            log.info("=============== undeployed app '" + appName + "'");
        }
    }

    @When("^I create and deploy (\\d+) applications using the topology template \"(.*?)\" and location \"([^\"]*)\"/\"([^\"]*)\"$")
    public void i_create_and_deploy_applications_using_the_topology_template_version(int appCount, String templateName, String orchestratorName,
            String locationName) throws Throwable {
        Map<Integer, Application> apps = Maps.newHashMap();
        for (int i = 0; i < appCount; i++) {
            String appName = "MyApp-" + i;
            log.info("=============== creating app '" + appName + "'");
            APPLICATION.I_create_a_new_application_with_name_and_description_based_on_the_template_with_name("MyApp-" + i, "a description", templateName);
            Application application = ApplicationStepDefinitions.CURRENT_APPLICATION;
            apps.put(i, application);
            DEPLOYMENT_TOPOLOGY.I_Set_a_unique_location_policy_to_for_all_nodes(orchestratorName, locationName);
            log.info("=============== deploying app '" + appName + "'");
            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.I_deploy_it();
            COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();
            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.The_application_s_deployment_should_succeed_after_minutes(15);
            log.info("=============== deployed app '" + appName + "'");
        }
        log.info("=============== Now we will undeploy all computes...");
        for (Application app : apps.values()) {
            ApplicationStepDefinitions.CURRENT_APPLICATION = app;
            log.info("=============== undeploying app '" + app.getName() + "'");
            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.I_undeploy_it();
            COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();
            log.info("=============== undeployed app '" + app.getName() + "'");
        }
    }

}

@@ -1024,875 +1024,8 @@
 );%0A%0A
-    @When(%22%5EI loop deploying/undeploying the app$%22)%0A    public void i_loop_deploying_undeploying_the_app() throws Throwable %7B%0A        int deployementCount = 0;%0A        while (true) %7B%0A            log.info(%22=============== Starting deployment #%22 + ++deployementCount);%0A            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.I_deploy_it();%0A            COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();%0A            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.The_application_s_deployment_should_succeed_after_minutes(15);%0A            log.info(%22=============== Ending deployment #%22 + deployementCount);%0A            APPLICATIONS_DEPLOYMENT_STEP_DEFINITIONS.I_undeploy_it();%0A            COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();%0A            log.info(%22=============== Ended deployment #%22 + deployementCount);%0A        %7D%0A    %7D%0A%0A
     
@@ -1442,33 +1442,17 @@
 g.info(%22
-=============== c
+C
 reating 
@@ -1761,33 +1761,17 @@
 g.info(%22
-=============== d
+D
 eploying
@@ -2087,33 +2087,17 @@
 g.info(%22
-=============== u
+U
 ndeployi
@@ -2171,32 +2171,41 @@
 P_DEFINITIONS.I_
+failsafe_
 undeploy_it();%0A 
@@ -2219,120 +2219,19 @@
     
-COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();%0A            log.info(%22=============== u
+log.info(%22U
 ndep
@@ -2781,25 +2781,9 @@
 fo(%22
-=============== c
+C
 reat
@@ -3225,33 +3225,17 @@
 g.info(%22
-=============== d
+D
 eploying
@@ -3555,25 +3555,9 @@
 fo(%22
-=============== d
+D
 eplo
@@ -3613,32 +3613,16 @@
 g.info(%22
-=============== 
 Now we w
@@ -3789,33 +3789,17 @@
 g.info(%22
-=============== u
+U
 ndeployi
@@ -3887,16 +3887,25 @@
 TIONS.I_
+failsafe_
 undeploy
@@ -3927,120 +3927,19 @@
     
-COMMON_STEP_DEFINITIONS.I_should_receive_a_RestResponse_with_no_error();%0A            log.info(%22=============== u
+log.info(%22U
 ndep

add failsafe undeploy step for long run test