/*
* 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 java.io.File;
import com.urbancode.air.AirPluginTool;
import com.urbancode.air.CommandHelper;

////////////// Read in plugin.xml properties /////////////
final def apTool = new AirPluginTool(this.args[0], this.args[1])
final def props = apTool.getStepProperties()
def profilePath          = props['profilePath']
def securityEnabled      = props['securityEnabled']
def authenticationTarget = props['authenticationTarget']
def loginUserid          = props['loginUserid']
def loginPassword        = props['loginPassword']
def encodePassword       = Boolean.valueOf(props['encodePassword'])
def additionalProps      = props['additionalProps']
// Separate Props into a List and remove any null/empty values
additionalProps = additionalProps.split('\n').findAll{it && it.trim().size() > 0} as List
additionalProps = additionalProps.collect {it.trim()}

final def isWindows = apTool.isWindows

////////////// Find soap.client.props /////////////
def soapClientProps = profilePath + File.separator + "properties" + File.separator + "soap.client.props"
println "[Action] Looking for soap.client.props..."
File scp = new File(soapClientProps)
if (!scp.isFile()){
    throw new FileNotFoundException("[Error] The soap.client.props at '${soapClientProps}' cannot be found. " +
            "Please ensure that it exists at this location.")
}
def scpText = scp.getText()
println "[Ok] soap.client.props found."

////////////// Find PropFilePasswordEncoder /////////////
def pwEncoder = ""
if (encodePassword) {
    println "[Action] Looking for PropFilePasswordEncoder script..."

    pwEncoder = profilePath + File.separator + "bin" + File.separator
    if (isWindows) {
        pwEncoder = pwEncoder + "PropFilePasswordEncoder.bat"
    }
    else {
        pwEncoder = pwEncoder + "PropFilePasswordEncoder.sh"
    }
    File pwEncoderFile = new File(pwEncoder)
    if (!pwEncoderFile.isFile()){
        throw new FileNotFoundException("[Error] The PropFilePasswordEncoder at '${pwEncoder}' cannot be found. " +
            "Please ensure that it exists at this location.")
    }
    println "[Ok] PropFilePasswordEncoder script found."
}
else {
    println "[Warning] Password will not be encoded!"
}

////////////// Create List of all Properties being Updated /////////////
def propList = []

if (securityEnabled != "ignore"){
    propList << "com.ibm.SOAP.securityEnabled=${securityEnabled}"
}

if (authenticationTarget != "ignore"){
    propList << "com.ibm.SOAP.authenticationTarget=${authenticationTarget}"
}

if (loginUserid){
    propList << "com.ibm.SOAP.loginUserid=${loginUserid}"
}

if (loginPassword){
    propList << "com.ibm.SOAP.loginPassword=${loginPassword}"
}

// Confirm the additional properties exist in soap.client.props
println "[Action] Checking that all entered properties are valid..."
for (prop in additionalProps){
    if (!prop.contains("=")){
        println "[Error]  The property '${prop}' does not have a '=' delimiter. For example: com.ibm.SOAP.securityEnabled=true"
        System.exit(1)
    }
    def vals = prop.split("=")
    // Check that variables exist beginning on a new line
    if (!scpText.contains("\n" + vals[0])) {
        println "[Error]  The property '${vals[0]}', which was parsed from from '${prop}, was not found in the soap.client.props file."
        println "[Possible Solution]  Confirm the variable exists, isolated, and on a new-line in the soap.client.props file."
        System.exit(1)
    }
    propList << prop
}
println "[Ok] Properties valid."

////////////// Update soap.client.props /////////////
// Replaces the variable and value that exists, isolated, on a new line.
// Any characters that were placed after the variable  (old value or extraneous information), will be wiped
for (prop in propList) {
    def vals = prop.split("=")
    scpText = scpText.replaceAll("[\n]${vals[0]}.*[^\n]", "\n" + prop)
}

// Create new temp file to encode the password
// Regardless of success or failure, this temp file will be deleted.
// Prevents the unencrypted password being left on the computer unintentionally
File tempSCP = new File("temp.txt")
tempSCP.deleteOnExit()
tempSCP.write(scpText)

if (encodePassword) {
    println "[Ok] Encoding password in temporary soap.client.props..."
    CommandHelper ch = new CommandHelper(new File("."))
    def args = [pwEncoder, tempSCP.getCanonicalPath(), "com.ibm.SOAP.loginPassword"]
    ch.runCommand("[Action] Encoding... ", args)
    println "[Ok] Password encoded."
}

println "[Action] Copying temporary file over to soap.client.props... "
scp.newWriter().withWriter { w ->
    w << tempSCP.getText()
}

println "[Ok] Successfully updated soap.client.props!"
