#!/usr/bin/env groovy
/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2002, 2017. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
import com.urbancode.air.AirPluginTool
import com.urbancode.air.plugin.rqm.RQMHelper
import com.urbancode.air.plugin.rqm.RQMUrlHelper

AirPluginTool apTool = new AirPluginTool(args[0], args[1])
final File workDir = new File('.').canonicalFile
final Properties props = apTool.getStepProperties()

println "[Ok] Discovered Input Properties:";
String user = props['user'].trim()
println "rqm_properties.user : " + user;

def password = props['password'];
println "rqm_properties.password: " + password;

def repository_url = props['repositoryUrl'].trim();
println "rqm_properties.repository_url: " + repository_url;
try{
    new URL(repository_url);
} catch(MalformedURLException e){
    println "[Error] Invalid RQM Repository URL: " + repository_url;
    e.printStackTrace();
    System.exit(1);
}

String project_name = props['projectName'];
println "rqm_properties.project_name: " + project_name;

String test_case_exec_record_id = props['testCaseExecRecordId'];
println "test_case_exec_record_id: " + test_case_exec_record_id;

def scriptId = props['scriptId'];
println "scriptId: " + scriptId;

def adapterId = props['adapterId'];
println "adapterId: " + adapterId;

// Adds required property to arguments
def arguments = RQMHelper.setRequiredArguments(props['arguments'].trim());
println "arguments: " + arguments;

def rqmExecutionTool  = props['rqmExecutionTool'];

// Find RQMExecutionTool as full path or within the given folder
File rqmFile = new File(rqmExecutionTool)
if (!rqmFile.isFile()) {
    rqmExecutionTool = rqmExecutionTool + File.separator + "RQMExecutionTool.jar"
    if (!new File(rqmExecutionTool).isFile()){
        throw new FileNotFoundException("[Error] Cannot find RQMExecutionTool.jar inside the given directory: '${rqmFile}'");
    }
}
println "RQMExecutionTool Path: " + rqmExecutionTool;

Boolean saveExecResultXML = props['saveResultXML'].toBoolean();
println "Save Execution Result XML: " + saveExecResultXML;
println "";

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

def pluginHomeFile = new File(PLUGIN_HOME);
if (!pluginHomeFile.exists()) {
    throw new RuntimeException("[Error] Cannot get PLUGIN_HOME");
}

AntBuilder ant = new AntBuilder();
String resultVerdict = '';
String resultURL = '';
String testCaseId = '';
String executionResultsStr = '';
String conciseExecutionResultsStr = '';

try {
    ant.path(id:"rqm.classpath") {
        pathelement(location:rqmExecutionTool)
    }
    ant.taskdef(name:"executeTestCaseER", classname:"com.ibm.rqm.executiontool.RQMExecuteTestCaseExecRecord", classpathref:"rqm.classpath")

    ant.executeTestCaseER(userId:"${user}",
            password:"${password}",
            rqmServerUrl:"${repository_url}",
            projectName:"${project_name}",
            testCaseExecRecordId:"${test_case_exec_record_id}",
            scriptId:"${scriptId}",
            adapterId:"${adapterId}",
            arguments:"${arguments}")
    println "[Ok] All ant properties are: " + ant.project.properties
    /*  for(p in ant.project.properties){
            println "Property:" + p.key + "and Value:" + p.value
        }
    }*/

    ant.echo('Result URL: ${rqmExec:result_url}');
    resultURL = ant.project.properties.'rqmExec:result_url';
    println "[Ok] Test case execution result url:  " + resultURL;

    ant.echo('Verdict: ${rqmExec:verdict}');
    resultVerdict = ant.project.properties.'rqmExec:verdict';

    testCaseId = resultURL.substring(resultURL.lastIndexOf(":")+1);
    println "[Ok] Test case execution result ID:  " + testCaseId;

    // Only run if a resultURL was found
    if (resultURL) {
        // Discover context, default is qm. jazz required for RQM pre-v3
        String context = "qm";
        if (repository_url.endsWith("jazz") || repository_url.endsWith("jazz/")) {
            context = "jazz";
        }

        // Retrieve Test Case Execution Results
        RQMUrlHelper helper = new RQMUrlHelper(user, password, context);
        File execResultXML = new File("testCaseExecutionRecord${testCaseId}.xml");
        if (!saveExecResultXML) {
            execResultXML.deleteOnExit();
        }
        helper.getExecute(resultURL, execResultXML.canonicalPath); // Retrieve the Result URL xml file
        println "RQMUrlHelper Result: " + execResultXML.text;

        // Parse Test Case Execution Results
        Map<String, List<String>> execResults = helper.parseTestCaseResults(execResultXML);
        // Generates list of: `stepIndex:Description:result` under the `testCaseExecutionResults` out prop
        execResults.each{key, value ->

            // Full Test Case Results
            executionResultsStr += key
            executionResultsStr += ":"
            executionResultsStr += value["description"]
            executionResultsStr += ":"
            executionResultsStr += value["result"]
            executionResultsStr += "\n"

            // Concise Test Case Results
            int lastPeriod = value["result"].lastIndexOf(".")
            String lastResult = value["result"].substring(lastPeriod+1).capitalize()
            conciseExecutionResultsStr += value["description"]
            conciseExecutionResultsStr += " - "
            conciseExecutionResultsStr += lastResult
            conciseExecutionResultsStr += "\n"
        }
    } else {
        println ""
        println "[Error] Unable to initiate the selected execution test. ResultURL was not found."
        println "[Possible Solution] Invalid Test Case Execution Record ID or Credentials."
    }

    if (!resultVerdict.contains("passed")) {
        throw new Exception("[Error] Test case execution record: ${test_case_exec_record_id} failed execution with a test case execution result status of: ${resultVerdict}");
    }

    println "[Ok] Test case execution result status:  " + resultVerdict;

} catch (Exception e ) {
    println "[Error] The test case execution record failed!";
    throw e;
} finally {
    // Write new environment name to output properties file
    apTool.setOutputProperty("projectName", project_name);
    apTool.setOutputProperty("resultVerdict", resultVerdict);
    apTool.setOutputProperty("resultURL", resultURL);
    apTool.setOutputProperty("testCaseId", testCaseId);
    apTool.setOutputProperty("testCaseExecutionResults", executionResultsStr);
    apTool.setOutputProperty("conciseTestCaseExecutionResults", conciseExecutionResultsStr);
    apTool.setOutputProperties();
}
