/*
* Licensed Materials - Property of IBM* and/or HCL**
* UrbanCode Deploy
* (c) Copyright IBM Corporation 2002, 2013, 2017. All Rights Reserved.
* (c) Copyright HCL Technologies Ltd. 2018. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*
* * Trademark of International Business Machines
* ** Trademark of HCL Technologies Limited
*/

import org.codehaus.jettison.json.JSONObject;
import org.codehaus.jettison.json.JSONArray;
import com.urbancode.air.AirPluginTool;
import com.urbancode.air.XTrustProvider;
import com.urbancode.ud.client.UDRestClient;
import com.urbancode.ud.client.ComponentClient;

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 finalURI = new URI(weburl);
def udClient = new ComponentClient(finalURI, user, password);
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");
    processProperties = udClient.getComponentProcessRequestProperties(compProcessRequestId);

    //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
    compareJSON = "";
    boolean retry = true;
    int retryCounter = 0;
    while (retry && retryCounter <= 10) {
        try {
            if (retryCounter > 0) {
                // wait before retrying
                sleep(5000);
                println "Retrying to get comparison JSON. Retry #" + retryCounter;
            }
            compareJSON = udClient.getComparisonJSON(workflowTraceId, activityTraceId, "ibm-ucd-resources.json");
            retry = false;
        }
        catch (Exception e){
            println "Exception when attempting to get the comparison JSON: " + e;
        }
        retryCounter = retryCounter + 1;
    }
    checkIfNullOrEmpty(compareJSON.toString(), "Comparison Output JSON");

    //show if there were differences found
    areDifferencesFound = String.valueOf(compareJSON.toString().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");
        }
    }
}

getDataFromLiveCompareStep();