/*
* 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 java.net.URLEncoder
import com.urbancode.ud.client.UDRestClient;
import com.urbancode.ud.client.ComponentClient;

def MAX_RETRIES = 3;


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 rootResourcePath = props['resourcePath'];
def webSphereUser = props['wasuser'];
def webSpherePassword = props['waspassword'];
def profilePath = props['profilePath'];
def wsadminPath = props['commandPath'];
def wasPort = props['port'];
def wasHost = props['host'];
def wasConnType = props['connType'];
def roleName = props['roleName'];
def compProcessRequestId = props['compProcessRequestId'];
def configurationTypes = props['configurationTypes'];

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

def isJythonUpgraded = {
    def jythonUpgrade = false;
    def wsadminExe = wsadminPath;
    while (wsadminExe.endsWith(File.separator)) {
        wsadminExe = wsadminExe.substring(0, wsadminExe.length()-1);
    }

    if (File.separator == "\\") {//windows platform
        wsadminExe = wsadminExe + File.separator + "wsadmin.bat";
    }
    else {
        wsadminExe = wsadminExe + File.separator + "wsadmin.sh";
    }

    def cmdArgs = [wsadminExe];

    cmdArgs << "-h";
    cmdArgs << "jython";

    println "Running Check to see if jython was upgraded";
    println cmdArgs.join(" ");

    Process proc = cmdArgs.execute();
    proc.out.close();
    OutputStream oStream = new ByteArrayOutputStream();
    OutputStream eStream = new ByteArrayOutputStream();
    proc.waitForProcessOutput(oStream, eStream);
    String output = oStream.toString();
    int usejython21 = output.indexOf("usejython21");
    if (usejython21 != -1) {
      jythonUpgrade = true;
    }

    return jythonUpgrade;
}

def getDataFromWsadmin = {
    def wsadminExe = wsadminPath;

    while (wsadminExe.endsWith(File.separator)) {
        wsadminExe = wsadminExe.substring(0, wsadminExe.length()-1);
    }

    if (File.separator == "\\") {//windows platform
        wsadminExe = wsadminExe + File.separator + "wsadmin.bat";
    }
    else {
        wsadminExe = wsadminExe + File.separator + "wsadmin.sh";
    }


    def cmdArgs = [wsadminExe];

    if (wasHost?.trim() && !wasHost.startsWith("p:")) {
        cmdArgs << "-host";
        cmdArgs << wasHost.trim();
    }

    if (wasPort?.trim() && !wasPort.startsWith("p:")) {
        cmdArgs << "-port";
        cmdArgs << wasPort.trim();
    }

    if (wasConnType?.trim() && !wasConnType.startsWith("p:")) {
        cmdArgs << "-conntype";
        cmdArgs << wasConnType.trim();
    }

    if ( webSphereUser?.trim() && !webSphereUser.trim().startsWith("p:")) {
        println "Using credentials";
        cmdArgs << "-user" << webSphereUser << "-password" << webSpherePassword;
    }

    cmdArgs << "-lang";
    cmdArgs << "jython";

    if (isJythonUpgraded() == true) {
        cmdArgs << "-usejython21";
        cmdArgs << "true";
    }

    cmdArgs << "-wsadmin_classpath" << "${WSDISC_HOME}" + java.io.File.separator + "lib" + java.io.File.separator + "securedata.jar" + java.io.File.pathSeparator + "${WSDISC_HOME}" + java.io.File.separator + "lib" + java.io.File.separator + "jettison-1.1.jar" + java.io.File.pathSeparator + "${WSDISC_HOME}" + java.io.File.separator + "lib" + java.io.File.separator + "log4j.jar" + java.io.File.pathSeparator + "${WSDISC_HOME}" + java.io.File.separator + "lib" + java.io.File.separator + "commons-codec.jar" + java.io.File.pathSeparator + "${WSDISC_HOME}" + java.io.File.separator + "lib" + java.io.File.separator + "CommonsUtil.jar"

    cmdArgs << "-f" << "${WSDISC_HOME}" + java.io.File.separator + "jythonScripts" + java.io.File.separator + "livecomp.py";

    cmdArgs << this.args[0].replace("\\","\\\\");

    println "Running Configuration Discovery";
    println cmdArgs.join(" ");

    Process proc = cmdArgs.execute();

    encKeyValuePair = "ucd.properties.secret=${apTool.getEncKey()}";
    proc.out.write(encKeyValuePair.getBytes());
    proc.out.close();

    OutputStream oStream = new ByteArrayOutputStream();
    OutputStream eStream = new ByteArrayOutputStream();
    proc.waitForProcessOutput(oStream, eStream);
    String output = oStream.toString();
    println output;

    checkIfNullOrEmpty(compProcessRequestId, "Component Process Request Id");

    //pull the component process request so we can get the workflow ID from it
    componentProcessRequest = udClient.getComponentProcessRequest(compProcessRequestId);
    checkIfNullOrEmpty(componentProcessRequest.toString(), "Component Process Request JSON");

    //pull workflow ID from the component process request
    workflowTraceId = componentProcessRequest.getJSONObject("rootTrace").getString("workflowTraceId");
    checkIfNullOrEmpty(workflowTraceId, "workflowTraceId");

    //send the payload to be set as application process properties so they can be accessed later
    udClient.setComponentProcessRequestProperty(compProcessRequestId, "workflowTraceId", workflowTraceId, false);
    udClient.setComponentProcessRequestProperty(compProcessRequestId, "activityTraceId", WE_ACTIVITY_ID, false);

    System.exit(proc.exitValue());
}

//check for nulls as well as provide an override for the error if it's safe to continue
private boolean checkIfNullOrEmpty(checkMe, checkedItemName, isError=true){
    if (checkMe == null || checkMe.isEmpty()){
        warningMsg = "$checkedItemName returned null or empty. Are the properties set correctly?";
        if (isError){
            throw new Exception(warningMsg);
        }
        else {
            //just a warning, tell the user but continue as normal
            println "WARNING: $warningMsg Further steps that depend on this one may not work correctly!";
            return true;
        }
    }
    return false;
}

private createPayloadJSON (name, value, isSecure){
    JSONObject result = new JSONObject();
    result.put("name", name);
    result.put("value", value);
    result.put("secure", isSecure);
    return result;
}

getDataFromWsadmin();
