/*
* Li/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Deploy
* (c) Copyright IBM Corporation 2011, 2014. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
/* This is an example step groovy to show the proper use of APTool
 * In order to use import these utilities, you have to use the "pluginutilscripts" jar
 * that comes bundled with this plugin example.
 */
import com.urbancode.air.AirPluginTool
import com.urbancode.air.CommandHelper
import org.apache.log4j.*
import com.urbancode.air.*
import com.urbancode.commons.httpcomponentsutil.HttpClientBuilder;
import com.urbancode.air.XTrustProvider;
import java.net.URI;
import java.nio.charset.Charset;
import com.urbancode.release.rest.framework.Clients;
import com.urbancode.release.rest.models.internal.PluginIntegrationProvider;
import com.urbancode.commons.httpcomponentsutil.HttpClientBuilder;
import com.urbancode.air.XTrustProvider;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.apache.http.client.HttpClient
import org.apache.http.client.*
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import com.urbancode.release.rest.models.internal.TaskExecution;
import com.urbancode.release.rest.models.internal.ScheduledDeployment;
import com.urbancode.air.PropsParser;
import com.urbancode.air.UCRPropsUtil;
import java.net.URI;

final def workDir = new File('.').canonicalFile

//Setup log4j
def currentDirectory = new File(getClass().protectionDomain.codeSource.location.path).parent
def config = new ConfigSlurper().parse(new File(currentDirectory+'/log4jSetup.groovy').toURL())
PropertyConfigurator.configure(config.toProperties())
Logger log = Logger.getInstance(getClass())

//Required imports
def apTool = new AirPluginTool(this.args[0], this.args[1]);
def props = apTool.getStepProperties();

//Required to access Release endpoints
def releaseToken = props['releaseToken'];
def extraProperties = props['extraProperties'];
//Useful for some operations
//it gets the ID of the integration provider running that step
def integrationProviderId = props['releaseIntegrationProvider'];

//All fields saved from the UI
//to be added automatically by the server
def serverUrl = props['releaseServerUrl'];
if (!serverUrl.endsWith("/")) {
    serverUrl = serverUrl+"/";
}

//To resolve property values
def ucrPropsUtil = new UCRPropsUtil();
def propsParser = new PropsParser();

def slackToken = props['token'];
def slackChannel = props['hookUrl'];
def proxyHost = props['proxyHost'];
def proxyPort = props['proxyPort'];
def proxyUser = props['proxyUser'];
def proxyPass = props['proxyPass'];
def slackMessageAtDeploymentStart = props['AtDeploymentStart'];
def slackMessageAtDeploymentEnd = props['AtDeploymentEnd'];
def slackMessageAtDeploymentAbort = props['AtDeploymentAbort'];
def slackMessageAtDeploymentCreated = props['AtDeploymentCreated'];
def slackMessageAtTaskFail = props['AtTaskFailure'];
def slackMessageAtDeploymentFail = props['AtDeploymentFailure'];
def releasePhases = props['releasePhases'];
def releaseNames = props['releaseNames'];

def message;
def event;
log.warn(serverUrl+" / "+releaseToken);

//Authentication
Clients.loginWithToken(serverUrl, releaseToken);
//The plugin task should have access to context properties
if (extraProperties != null) {
    def slurper = new groovy.json.JsonSlurper()
    def currentTaskExtra = slurper.parseText(extraProperties)

    //-------------------------------------------------
    event = currentTaskExtra.event;
    log.warn("********************************************************");
    log.warn(event);
    if (!releasePhases.isEmpty()) log.warn("Release Phases "+releasePhases);
    if (!releaseNames.isEmpty()) log.warn("Release Names "+releaseNames);


    log.warn("********************************************************");

    if (event.equals("AtDeploymentAbort") || event.equals("AtDeploymentStart") || event.equals("AtDeploymentEnd") || event.equals("AtDeploymentCreated")) {

         ScheduledDeployment sdDetail = new ScheduledDeployment();
         log.warn("SD ID => "+currentTaskExtra.scheduledDeployment.id);
         def sdId = currentTaskExtra.scheduledDeployment.id
         //We load more information about the SD
         sdDetail = sdDetail.id(sdId+"")
         sdDetail.format("detail")
         sdDetail = sdDetail.get()

         def currentSdPhase = sdDetail.phase.phaseModel.name;
         def currentReleaseName = sdDetail.release.name;

         log.warn("Current Release Name "+currentReleaseName);
         log.warn("Current Phase Name "+currentSdPhase);

         def shouldBeSkipped = false;

         def matchingPhase;
         def matchingRelease;

         if (!releasePhases.isEmpty()) {
             def phases = releasePhases.split(",")
             for (String p : phases) {
                  if (p.trim().equals(currentSdPhase)) {
                      matchingPhase = p;
                  }
             }
         }

         if (!releaseNames.isEmpty()) {
             def releases = releaseNames.split(",")
             for (String r : releases) {
                  if (r.trim().equals(currentReleaseName)) {
                      matchingRelease = r;
                  }
             }
         }

         if (!releasePhases.isEmpty() && matchingPhase == null) {
             shouldBeSkipped = true
         }

         if (!releaseNames.isEmpty() && matchingRelease == null) {
             shouldBeSkipped = true
         }

         if (!shouldBeSkipped) {

	         //We load some other pretty useful information
	         def extraData = ucrPropsUtil.getExtraProperties(props, sdDetail, null)

	         if (event.equals("AtDeploymentAbort")) {
		         if (slackMessageAtDeploymentAbort != null && slackMessageAtDeploymentAbort != "") {
		             message = slackMessageAtDeploymentAbort;
		         }
		         else {
		             message = "Deployment "+currentTaskExtra.scheduledDeployment.name+" was aborted "
		         }
	         }
	         if (event.equals("AtDeploymentCreated")) {
		         if (slackMessageAtDeploymentCreated != null && slackMessageAtDeploymentCreated != "") {
		             message = slackMessageAtDeploymentCreated;
		         }
		         else {
		             message = "Deployment "+currentTaskExtra.scheduledDeployment.name+" was created "
		         }
	         }
	         else if (event.equals("AtDeploymentEnd")) {
	         	 if (slackMessageAtDeploymentEnd != null && slackMessageAtDeploymentEnd != "") {
		             message = slackMessageAtDeploymentEnd;
		         }
		         else {
		             message = "Deployment "+currentTaskExtra.scheduledDeployment.name+" was completed "
		         }
	         }
	         else if (event.equals("AtDeploymentStart")) {
	         	 if (slackMessageAtDeploymentStart != null && slackMessageAtDeploymentStart != "") {
		             message = slackMessageAtDeploymentStart;
		         }
		         else {
		             message = "Deployment "+currentTaskExtra.scheduledDeployment.name+" was started "
		         }
	         }
	         else if (event.equals("AtDeploymentFail")) {
	         	 if (slackMessageAtDeploymentFail != null && slackMessageAtDeploymentFail != "") {
		             message = slackMessageAtDeploymentFail;
		         }
		         else {
		             message = "Deployment "+currentTaskExtra.scheduledDeployment.name+" was failed "
		         }
	         }

	         message = propsParser.parseSingleValue(message, extraData, sdDetail, null)

	         log.warn("---------------------------------------------------------");
	         log.warn(" SD MESSAGE => "+message);
	         log.warn("---------------------------------------------------------");

         }
         else {

	         log.warn("---------------------------------------------------------");
	         log.warn(" WILL BE SKIPPED, NO RELEASES OR PHASES FOUND ");
	         log.warn("---------------------------------------------------------");

         }
    }
    else if (event.equals("AtTaskFail")) {
        log.warn("---------------------------------------------------------");
        log.warn(" SD MESSAGE => "+currentTaskExtra.task.id);
        log.warn("---------------------------------------------------------");

		def task = new TaskExecution()

        task.id(currentTaskExtra.task.id)
        task.format("plugin")
        task = task.get()


        //We load some other pretty useful information
        def extraData = ucrPropsUtil.getExtraProperties(props, null, task)

        if (slackMessageAtTaskFail != null && slackMessageAtTaskFail != "") {
	        message = slackMessageAtTaskFail;
        }
        else {
            message = "Task Failed "+currentTaskExtra.task.name+" was started "
        }
        message = propsParser.parseSingleValue(message, extraData, null, task)

        log.warn("---------------------------------------------------------");
        log.warn(" SD MESSAGE => "+message);
        log.warn("---------------------------------------------------------");

    }

	log.warn("---------------------------------------------------------");
	log.warn(" SD MESSAGE => "+slackChannel);
	log.warn("---------------------------------------------------------");

    if (message != null) {

		HttpClientBuilder builder = new HttpClientBuilder();
		builder.setTrustAllCerts(true);

        if (proxyHost) {
            builder.setProxyHost(proxyHost)
            builder.setProxyPort(Integer.valueOf(proxyPort))

            if (proxyUser) {
                builder.setProxyUsername(proxyUser)
                builder.setProxyPassword(proxyPass)
            }
        }

		def client = builder.buildClient();
		HttpPost methodPost = new HttpPost(slackChannel);
		def messageToPost = "{'text':'"+message+"'}"
		methodPost.addHeader("Accept", "application/json")
		methodPost.addHeader("Content-Type", "application/json")
		StringEntity postEntity = new StringEntity(messageToPost)
		methodPost.setEntity(postEntity)

		HttpResponse responsePost = client.execute(methodPost);
		int status = responsePost.getStatusLine().getStatusCode();

		log.warn("RESPONSE CODE=>"+responsePost.getStatusLine().getStatusCode())

     }

}


