#!/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_suite_exec_record_id = props['testSuiteExecRecordId'];
println "test_suite_exec_record_id: " + test_suite_exec_record_id;

def step_script_ids = props['stepScriptIds'];
println "step_script_ids: " + step_script_ids;

def step_adapter_ids = props['stepAdapterIds'];
println "step_adapter_ids: " + step_adapter_ids;


// 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 testSuiteId = '';
String executionResultsStr = '';
String conciseExecutionResultsStr = '';
Map<String, String> suiteResults = [:];

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

    ant.executeTestSuiteER(userId:"${user}",
    password:"${password}",
    rqmServerUrl:"${repository_url}",
    projectName:"${project_name}",
    testSuiteExecRecordId:"${test_suite_exec_record_id}",
    suiteStepScriptIds:"${step_script_ids}",
    suiteStepAdapterIds:"${step_adapter_ids}",
    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 suite execution result url:  " + resultURL;

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

    testSuiteId = resultURL.substring(resultURL.lastIndexOf(":")+1)
    println "[Ok] Test suite execution result id:  " + testSuiteId;

    // 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 Suite Execution Results
        RQMUrlHelper helper = new RQMUrlHelper(user, password, context);
        File execResultXML = new File("testSuiteExecutionRecord${testSuiteId}.xml");
        if (!saveExecResultXML) {
            execResultXML.deleteOnExit();
        }
        helper.getExecute(resultURL, execResultXML.canonicalPath); // Retrieve the Result URL xml file
        println "RQMUrlHelper Result: " + execResultXML.text;

        // Parse Overall Results
        suiteResults = helper.parseTestSuiteResults(execResultXML);

        // Parse All Execution Result Urls
        Map<String, List<String>> executionResults= helper.parseTestSuiteExecutionResults(execResultXML, saveExecResultXML);
        // Generates list of: `testCaseResultID:Title:result` under the `executionResults` out prop
        executionResults.each{key, value ->

            // Full Test Suite Results
            executionResultsStr += key
            executionResultsStr += ":"
            executionResultsStr += value["title"]
            executionResultsStr += ":"
            executionResultsStr += value["state"]
            executionResultsStr += "\n"

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

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

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

} catch (Exception e) {
    println "[Error] The test suite 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("testSuiteId", testSuiteId);
    apTool.setOutputProperty("executionResults", executionResultsStr);
    apTool.setOutputProperty("conciseExecutionResults", conciseExecutionResultsStr);
    suiteResults.each{key, value ->
        apTool.setOutputProperty((String)key, value);
    }
    apTool.setOutputProperties();
}
