/*
* Licensed Materials - Property of IBM* and/or HCL**
* UrbanCode Deploy
* (c) Copyright IBM Corporation 2002, 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;
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 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 configurationTypes = props["configurationTypes"]
def configOutputFile = props["configurationOutputFile"]
def maxHeap = props["wasAdminMaxHeap"]

def outFile = "out.json";

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

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;
    }

    if (maxHeap?.trim()) {
        cmdArgs << "-javaoption";
        cmdArgs << maxHeap?.trim();
    }

    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 + "confdiscover.py";

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

    def ofile = new File(outFile);
    def outputFileAbs = ofile.getAbsolutePath();
    outputFileAbs = outputFileAbs.replace("\\","\\\\");
    cmdArgs << outputFileAbs;

    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();
    //prevent the "WASX7309W: No "save" was performed" warning message
    // from appearing in the console when performing a discovery
    int warningStart = output.indexOf("WASX7309W");
    if (warningStart != -1) {
        // remove everything after and including WASX7309W
        output = output.substring(0,warningStart);
    }
    println output
    return output;
}

// Set output file.  Clean any previous version and create output file directory if needed.
// In case user runs this from resource tree, check for configOutputFile first
if (configOutputFile) {
    outFile = configOutputFile?.replace("\\", "\\\\").trim();
    try {
        def ofile = new File(outFile);
        if (ofile.exists()) {
            ofile.delete();
        }
        outputFileAbs = ofile.getAbsolutePath()
        outputFileDirString = new File(outputFileAbs).getParent()
        outputFileDir = new File(outputFileDirString)
        if (!outputFileDir.exists()) {
            if (!outputFileDir.mkdirs()) {
                throw new RuntimeException("Failed to create directory " + outputFileDirString);
            }
        }
        //test creating a file and reading it
        ofile.write("")
        ofile.getText('UTF-8')
    }
    catch (IOException e) {
        throw new RuntimeException(e);
    }
}

// Invoke wsadmin to discover configuration
def data = getDataFromWsadmin();

// Load the discovered configuration
def jsonData = ""
try {
    def jsonFile = new File(outFile);
    jsonData = jsonFile.getText('UTF-8');
}
catch (IOException e) {
    throw new RuntimeException("When attempting to load finished discovery data from configuration file: $e");
}

JSONArray array = new JSONArray(jsonData);
if (array.length() > 0) {
    for (int i = array.length() - 1; i >= 0; i--) {
        JSONObject obj = array.getJSONObject(i);
        if (obj.has("roleName") && obj.getString("roleName").equals("WebSphereCell")) {
            //we need to update the root json object with
            // user, password, profilePath, and commandPath
            JSONObject roleProperties = obj.getJSONObject("roleProperties");
            roleProperties.put("websphere.user", webSphereUser);
            roleProperties.put("websphere.port", wasPort);
            roleProperties.put("websphere.connType", wasConnType);
            roleProperties.put("websphere.password", webSpherePassword);
            roleProperties.put("websphere.commandPath", wsadminPath);
            roleProperties.put("websphere.profilePath", profilePath);
            roleProperties.put("websphere.cell.configurationtypes", configurationTypes);
            break;
        }
    }
    if (configOutputFile?.trim()) {
       apTool.setOutputProperty("configurationOutputFile", configOutputFile.trim());
    }
    else {
       // If we are here we were likely invoked from the UI.  Send the
       // discovered JSON data to stdout so it is available from the UI.
       println array.toString(4);
       apTool.setOutputProperty("resources", array.toString());
    }
}
else {
    apTool.setOutputProperty("resources", data);
    throw new RuntimeException('Configuration Discovery returned no data');
}
apTool.storeOutputProperties();
