/*
* Licensed Materials - Property of IBM* and/or HCL**
* UrbanCode Deploy
* UrbanCode Build
* UrbanCode Release
* AnthillPro
* (c) Copyright IBM Corporation 2011, 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
*/
package com.ibm.urbancode.zos.common

public class TSOHelper {
	def ispfGatewayPath 
	def reuseSession  //boolean
	def serviceType
	def ispProf
	def outputText
	def errorText
	def returnCode
	def reasonCode
	def operationsLog
	def debug = false
	
	def runCommand(tsoCommand){
		if(!tsoCommand || tsoCommand.length() < 1){
			throw new IllegalArgumentException("Command should not be empty");
		}
		if(!ispfGatewayPath || ispfGatewayPath.length() < 1){
			throw new IllegalArgumentException("ISPF Gateway Path should not be empty");
		}

		def ispfzxml = ispfGatewayPath + "/ISPZXML";
		debug(ispfzxml)

		if(serviceType != "ISPF"){
			serviceType="TSO"
		}

		outputText = ""
		operationsLog = ""
		returnCode = 0
		reasonCode = ""

		//build request xml
		def inputXMLWriter = new StringWriter();
		inputXMLWriter.append('<?xml version=\"1.0\"?>\n' );
		def inputXML = new groovy.xml.MarkupBuilder(inputXMLWriter);
		inputXML.setDoubleQuotes(true);
		inputXML.'ISPF-INPUT'(){
			'SERVICE-REQUEST'(){
				service(serviceType)
				session(reuseSession? "REUSE" : "NONE")
				command(tsoCommand)
				if(serviceType=="ISPF"){
					ispprof(ispProf)
				}
			}
		};
		debug('===============================')
		debug("request XML")
		debug(inputXMLWriter)
	
		def commandLine = []
		commandLine.add(ispfzxml)
	
		final def processBuilder = new ProcessBuilder(commandLine as String[])
		def path = System.getenv("PATH")
		processBuilder.environment().put("PATH",path + ":" + ispfGatewayPath)
	
		final def process = processBuilder.start()
		
		final def processInput = new PrintWriter(new OutputStreamWriter(process.getOutputStream()))
		//Send input XML
		processInput.println(inputXMLWriter)
		processInput.flush()
	    
	    //Commented below 2 lines and added after buffered reader  
		//process.out.close() 
		//process.waitFor()
		
		//parse respone XML
		BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))
		def line = null
		def outputXMLString = new StringBuffer()
		while((line = br.readLine()) != null) {
			if(line.trim().startsWith("Connection Protocol")){ //skip lines which cause XML parsing problem
				continue
			}
			outputXMLString.append(line).append('\n')
		}
		
		process.out.close() 
		process.waitFor()
		
		try{
			def xmlContent = outputXMLString.toString()
			def xmlpos = xmlContent.indexOf("<?xml version") //skip the HTTP header
			if(xmlpos != -1){
				xmlContent = xmlContent.substring(xmlpos)  
			}else{
				println("Failed to get response XML from ISPF Gateway.")
				return -1
			}
		
			debug('===============================')
			debug("response XML")
			debug(xmlContent)
			def outputXML = new XmlParser().parseText(xmlContent)
			operationsLog = outputXML.'OPERATIONS-LOG'.text()
			
			if(serviceType == "TSO"){
				outputText = outputXML.'SERVICE-RESPONSE'.TSO.text()
			}else if(serviceType == "ISPF"){
				outputText = outputXML.'SERVICE-RESPONSE'.ISPF.text()
				returnCode = Integer.parseInt (outputXML.'SERVICE-RESPONSE'.'RETURN-CODE'.text())
				if(returnCode > 0){
					reasonCode = ""
					outputXML.'SERVICE-RESPONSE'.'REASON-CODES'.'REASON-CODE'.each{
						reasonCode += "${it.@ID}: ${it.text()}\n"
					}
				}else{
					def CLISTERRORTEXT = "The initially invoked CLIST ended with a return code = "
					def pos = outputText.indexOf(CLISTERRORTEXT)
					if(pos > 0){
						try{
							returnCode = Integer.parseInt(outputText.substring(pos + CLISTERRORTEXT.length()))
						}catch(Exception e){
							println "Error parsing return code."
						}
					}
				}
			}
		}catch (Exception e) {
		    println(outputXMLString.toString())
			throw e
		}

		return process.exitValue()	
	}
	
	def runCommandFromUSS(tsoCommand){

		outputText = ""
		errorText = ""
		returnCode = 0
		
		def commandLine = []
	
		final def processBuilder = new ProcessBuilder(commandLine as String[])
        
		def process = ("tsocmd "+tsoCommand).execute();
		def out = new StringBuilder()
		def err = new StringBuilder()
		process.waitForProcessOutput(out, err);
		returnCode = process.exitValue();
		outputText=out.toString();
		errorText=err.toString();
	}
	
	def debug(s){
		if(debug) println(s)
	}			
	
}
