/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2002, 2013. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
import org.codehaus.jettison.json.JSONObject;
import org.codehaus.jettison.json.JSONArray;
import com.urbancode.air.AirPluginTool;
import com.urbancode.air.XTrustProvider;
import java.net.URLEncoder
import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.auth.AuthScope;

XTrustProvider.install();

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

def weburl = System.getenv("AH_WEB_URL");
def user = apTool.getAuthTokenUsername();
def password = apTool.getAuthToken();
def compProcessRequestId = props['compProcessRequestId']
def isFailWhenDifferencesFound = props['isFailWhenDifferencesFound']
def exitCode = 0

def WSDISC_HOME = System.getenv("PLUGIN_HOME");

def getDataFromLiveCompareStep = {
    //retrieve application process properties
    checkIfNullOrEmpty(compProcessRequestId, "Component Process Request ID");
    processPropertiesRESTURL = "$weburl/rest/deploy/componentProcessRequest/$compProcessRequestId/properties";
    processProperties = new JSONObject(executeGetMethod(processPropertiesRESTURL, user, password, false));
    processProperties = processProperties.getJSONArray("properties");

    //retrieve workflow and activity ID's from application process properties
    workflowTraceId = findPropValueFromJSON("workflowTraceId", processProperties);
    activityTraceId = findPropValueFromJSON("activityTraceId", processProperties);
    checkIfNullOrEmpty(workflowTraceId, "workflowTraceId");
    checkIfNullOrEmpty(activityTraceId, "activityTraceId");

    //run the rest call to retrieve comparison JSON using ID's from the compare step that ran previously
    compareRESTURL = "$weburl/rest/logView/trace/compare/$workflowTraceId/$activityTraceId/ibm-ucd-resources.json";
    compareJSON = executeGetMethod(compareRESTURL, user, password, true);
    checkIfNullOrEmpty(compareJSON, "Comparison Output JSON");

    //show if there were differences found
    areDifferencesFound = String.valueOf(compareJSON.contains("CHILDREN_CHANGED"))
    apTool.setOutputProperty("areDifferencesFound", areDifferencesFound);
    //set link to the request for the user's convenience
    apTool.setOutputProperty("compareProcessRequestLink", "$weburl/#componentProcessRequest/$compProcessRequestId");
    apTool.setOutputProperties();

    //throw a failure status via -1 exit code
    if (areDifferencesFound == "true" && isFailWhenDifferencesFound == "true"){
        exitCode = -1
        println "Configuration differences found and 'Fail When Differences Found' was checked. Throwing Failure status to indicate differences found."
    }

    System.exit(exitCode);
}

private checkIfNullOrEmpty(checkMe, checkedItemName){
    if (checkMe == null || checkMe.isEmpty()){
        throw new Exception("$checkedItemName returned null or empty. " +
                            "Are the properties set properly? " +
                            "Has the WebSphere Comparison Step run before this one? " +
                            "Is this Component Process triggered from an Application Process?");
    }
}

private findPropValueFromJSON (searchName, searchJSONArray){
    for (int i = 0; i < searchJSONArray.length(); i++){
        JSONObject thisObject = searchJSONArray.get(i)
        thisName = thisObject.getString("name");
        if (thisName.equals(searchName)){
            return thisObject.getString("value");
        }
    }
}

private executeGetMethod (requestRESTURL, ucdUsername, ucdPassword, isRetry) {
    HttpMethod method = new GetMethod(requestRESTURL);

    Credentials defaultcreds = new UsernamePasswordCredentials(ucdUsername, ucdPassword);
    HttpClient client = new HttpClient();
    client.getState().setCredentials(AuthScope.ANY, defaultcreds);
    client.getParams().setAuthenticationPreemptive(true);

    def methodResult = client.executeMethod(method);
    def response = method.getResponseBodyAsString();

    //need to retry a couple times to make sure the files
    //have time to upload to the server
    if (methodResult != 200) {
        if (isRetry){
            for (int i = 0; i < 6; i++){
                methodResult = client.executeMethod(method);
                response = method.getResponseBodyAsString();

                if (methodResult == 200){
                    return response;
                }
                Thread.sleep(10000);
            }
            throw new Exception ("60 second timeout with code ${methodResult}: ${response}. Are the ID properties set correctly?");
        }
        else {
            throw new Exception ("Received response ${methodResult}: ${response}");
        }
    }

    return response;
}

getDataFromLiveCompareStep();