/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2002, 2014. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/


import com.ibm.urbancode.zos.common.RexxHelper;
import com.urbancode.air.AirPluginTool

try {
	def apiTool = new AirPluginTool(this.args[0], this.args[1])
	def props = apiTool.getStepProperties()

	// verify parameter format
	def sourcePDS
	def toPDS
	def includeMembers
	def excludeMembers
	def isLoadModule=Boolean.valueOf(props['isLoadModule'])
	try {
		sourcePDS = verifyDatasetName(props['sourcePDS']);
		toPDS = verifyDatasetName(props['toPDS']);
		if(!toPDS.startsWith("'")){
			toPDS = "'" + toPDS;
		}
		if(!toPDS.endsWith("'")){
			toPDS = toPDS+ "'";
		}
		
		if (!sourcePDS.equals(toPDS)) {
			includeMembers = verifyMembers(props['includeMembers'])
			excludeMembers = verifyMembers(props['excludeMembers'])
		}
	} catch (Exception e1) {
		apiTool.setOutputProperty("returnCode", 8.toString());
		apiTool.setOutputProperties();
		apiTool.err.println('Error verifying parameters.')
		e1.printStackTrace();
		System.exit(8);
	}

	try {
		//generate a rexx script to copy pds
		def logFile =File.createTempFile("COPY",".SYSPRINT")
		def rexxScript = generateRexxScript(sourcePDS, toPDS, includeMembers, excludeMembers ,isLoadModule,logFile);
		def rexxHelper = new RexxHelper()
		def returnCode = rexxHelper.execute(rexxScript, "cp037")
		logFile.eachLine {line->
			apiTool.out.println(line)
		}
		logFile.deleteOnExit()
		if (returnCode == 0) {
			apiTool.out.println("Copy data set completed.")
			apiTool.out.println(rexxHelper.getOutput())
		} else {
			apiTool.err.println(rexxHelper.getOutput())
			apiTool.err.println('Program terminated with return code ' + returnCode.toString())
			apiTool.err.println(rexxHelper.getError())
		}

		apiTool.setOutputProperty("returnCode", returnCode.toString());
		apiTool.storeOutputProperties();//write the output properties to the file

	} catch (Exception e) {
		e.printStackTrace();
		apiTool.setOutputProperty("returnCode", 8.toString());
		apiTool.storeOutputProperties();//write the output properties to the file
		System.exit(8)
	}
} catch (Exception e) {
	println "${e.message}";
	e.printStackTrace();
	System.exit(1);
}

def generateRexxScript(sourcePDS, toPDS, includeMember, excludeMemeber,isLoadModule,File log) {
    def controllines = []
    def inputdds = []
    def freedds = []
    def inddlist = []

    if (sourcePDS) {
        def lines = sourcePDS.split(System.getProperty("line.separator"))
        int length = lines.size();
        for (int i = 0; i < length; i++) {
            if (lines[i].trim()) {
                def line = lines[i].split(",")
                if (line.size() > 1) {
                    inddlist.add("(INDD$i,R)")
                } else if (line.size() > 0) {
                    inddlist.add("INDD$i")
                } else {
                    continue
                }
				
				def tempdsname = line[0].trim()
				if(!tempdsname.startsWith("'")){
					tempdsname = "'" + tempdsname;
				}
				if(!tempdsname.endsWith("'")){
					tempdsname = tempdsname+ "'";
				}
				inputdds.add(
						"""\"ALLOC DATASET($tempdsname) DDNAME(INDD$i) SHR  REUSE\"
                    say "Allocation for data set ${tempdsname} ends with "rc
                    if rc <> 0 then return 8""")
                freedds.add("\"FREE DDNAME(INDD$i)\"")
            }
        }
		if (isLoadModule) {
			statement = "COPERST1 COPYMOD OUTDD=SYSUT2"			
		} else {
			statement = "COPERST1 COPY OUTDD=SYSUT2"
		}
		controllines.add(statement);
        inddlist.each {inputdd->
			controllines.add("              INDD=($inputdd)")
        }
    }
    if (includeMember) {
        if (excludeMemeber) {
            throw new InvalidPropertiesFormatException(
                    "Include Memebers and Exclude Members are mutually exclusive."
            )
        }
        def lines = includeMember.split(System.getProperty("line.separator"))
        lines.each { line ->
            if (line.trim()) {
                if (line.toString().contains("(")) {
                    controllines.add("         SELECT MEMBER=(${line})")
                } else if (line.toString().contains(",")) {
                    controllines.add("         SELECT MEMBER=((${line}))")
                } else {
                    controllines.add("         SELECT MEMBER=${line}")
                }
            }
        }
    } else if (excludeMemeber) {
        def lines = excludeMemeber.split(System.getProperty("line.separator"))
        lines.each { line ->
            if (line.trim()) {
                controllines.add("        EXCLUDE MEMBER=${line}")
            }
        }
    }
	def sysinFile = File.createTempFile("COPY",".SYSIN")
    controllines.each { line ->
        sysinFile.append("${line.padRight(80)}")
    }
    def ddstatement = ""
    inputdds.each { line ->
        ddstatement = "$ddstatement$line\n"
    }
    def freeDDstatement = ""
    freedds.each { line ->
        freeDDstatement = "$freeDDstatement$line\n"
    }

	sysinFile.deleteOnExit();
    def result = """/* rexx */
userid = USERID()
ADDRESS TSO
"ALLOC PATH('${sysinFile.canonicalFile}') DDNAME(SYSIN) PATHDISP(DELETE,DELETE) PATHOPTS(ORDONLY) PATHMODE(SIRUSR) "
if rc <> 0 then
do
    say 'Error allocating SYSIN for IEBCOPY '
    return 8
end
$ddstatement
"ALLOC DATASET($toPDS) DDNAME(SYSUT2) SHR  REUSE"
if rc <> 0 then
do
 say 'Error allocating DD for To PDS'
 return 8
end
"alloc path('${log.canonicalFile}') DDNAME(SYSPRINT) FILEDATA(TEXT) pathdisp(keep,keep) pathopts(owronly,ocreat) PATHMODE(SIRUSR)"
ADDRESS TSO 'LISTALC STATUS'
ADDRESS TSO 'IEBCOPY'
exitRC =rc
if rc <> 0 then say 'Error executing IEBCOPY'
$freeDDstatement
"FREE DDNAME(SYSUT2) "
if rc <> 0 then say 'Error free To PDS'
"FREE DDNAME(SYSPRINT) "
"FREE DDNAME(SYSIN) "
return exitRC
"""
    return result
}

def verifyDatasetName(name) {
    if (name) {
        name = name.trim()
        if (name.length() > 0) {
            return name
        }
    }
    throw new InvalidPropertiesFormatException("$name is not an valid data set name")
    return null;
}

def verifyMembers(members) {
    if (members) {
        return members = members.trim()
    }
}

System.exit(0);