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

package com.urbancode.air.plugin.rqm

import com.urbancode.air.CommandHelper
import groovy.util.XmlSlurper

public class RQMUrlHelper {

    private final String GET    = "GET"
    private final String PUT    = "PUT"
    private final String POST   = "POST"
    private final String DELETE = "DELETE"
    private File workDir     = new File(".").canonicalFile
    private CommandHelper ch = new CommandHelper(workDir)

    private String username
    private String password
    private String context
    private String rqmUrlUtility

    RQMUrlHelper(String username, String password, String rqmUrlUtility) {
        this.username = username
        this.password = password
        this.rqmUrlUtility = rqmUrlUtility
    }

    RQMUrlHelper(String username, String password, String context, String rqmUrlUtility) {
        this.username = username
        this.password = password
        this.context  = context
        this.rqmUrlUtility = rqmUrlUtility
    }

    /**
     * @param url   The resultURL of the execution result to retrieve
     * @param filepath Output file location
     * @return      Retrieves the XML from the given url and saves it to the given file
     */
    private void getExecute(String url, String filepath) {
        List<String> commandArgs = init(GET)

        commandArgs << "-user"
        commandArgs << username

        commandArgs << "-password"
        commandArgs << password

        if (context) {
            commandArgs << "-context"
            commandArgs << context
        }

        commandArgs << "-filepath"
        commandArgs << filepath

        commandArgs << "-url"
        commandArgs << url

        ch.runCommand("[Action] Gathering Execution Result Data: ", commandArgs)
    }

    /**
     * @param operator CRUD command to initialize the commandArgs
     * @return Command Args with the required beginning props for RQMUrlUtility cli
     */
    private List<String> init(String operator) {
        if (![GET, PUT, POST, DELETE].contains(operator)) {
            throw new Exception("[Error] Invalid CRUD operator given. Please contact your plugin developer.");
        }

        List<String> result = []
        result << System.getenv("JAVA_HOME") + File.separator + "bin" + File.separator + "java"
        result << "-jar"
        result << rqmUrlUtility
        result << "-command"
        result << operator
        return result
    }

    /**
     * @param input The input execution result XML file
     * @return Map of the test case's step results. Key:stepIndex, Value: [Description, Result]
     */
    private Map<String, Map<String, String>> parseTestCaseResults(File input) {
        Map<String, String> result = [:]

        println "\n"
        def xml = new XmlSlurper().parseText(input.text)
        xml.stepResults.stepResult.each {it ->
            Map<String, String> props = [:]
            println "[Result]: ${it.@stepIndex}:${it.description.text()}:${it.result.text()}"
            props["description"] = it.description.text()
            props["result"]  = it.result.text()
            result.put(it.@stepIndex, props)
            it.stepResults.stepResult.each{subIt ->
                Map<String, String> subProps = [:]
                println "[Result]: ${it.@stepIndex}.${subIt.@stepIndex}:${it.description.text()}:${subIt.result.text()}"
                subProps["description"] = it.description.text()
                subProps["result"] = subIt.result.text()
                result.put("${it.@stepIndex}.${subIt.@stepIndex}", subProps)
            }
        }
        return result
    }

    /**
     * @param input The input execution result XML file
     * @return Map of each overall test suite results Key:testResultType, Value: numericalResult
     */
    private Map<String, String> parseTestSuiteResults(File input) {
        Map<String, String> result = [:]

        def xml = new XmlSlurper().parseText(input.text)
        result.put("testcasestotal",            xml?.testcasestotal.text())
        result.put("testcasespassed",           xml?.testcasespassed.text())
        result.put("testcasesfailed",           xml?.testcasesfailed.text())
        result.put("testcasesblocked",          xml?.testcasesblocked.text())
        result.put("testcasesinconclusive",     xml?.testcasesinconclusive.text())
        result.put("testcasesinprogress",       xml?.testcasesinprogress.text())
        result.put("testcasesnotstarted",       xml?.testcasesnotstarted.text())
        result.put("testcasesincomplete",       xml?.testcasesincomplete.text())
        result.put("testcasespartiallyblocked", xml?.testcasespartiallyblocked.text())
        result.put("testcaseserror",            xml?.testcaseserror.text())
        result.put("testcasespermfailed",       xml?.testcasespermfailed.text())
        result.put("testcasesdeferred",         xml?.testcasesdeferred.text())
        result.put("testcasespaused",           xml?.testcasespaused.text())
        return result
    }

    /**
     * @param input The input execution result XML file
     * @return Map of each test case's result. Key:ID, Value: [Description, Result]
     */
    private Map<String, Map<String,String>> parseTestSuiteExecutionResults(File input, Boolean saveExecResults) {
        Map<String, Map<String,String>> result = [:]
        def slurper = new XmlSlurper()
        def xml = slurper.parseText(input.text)
        xml?.executionresult.each{ it ->
            String url   = it.@href
            String id    = url.substring(url.lastIndexOf(":")+1)
            if (!id.isNumber()) {
                id = url.substring(url.lastIndexOf("/")+1)
            }
            File temp = new File("testCaseExecutionRecord${id}.xml")
            if (!saveExecResults) {
                temp.deleteOnExit()
            }
            getExecute(url, temp.canonicalPath)
            def resultXml = slurper.parseText(temp.text)

            Map<String,String> props = [:]
            props["title"] = resultXml?.title.text()
            props["state"] = resultXml?.state.text()
            result.put(id, props)
        }
        return result
    }


    // private List<String> parseTestSuiteExecutionIds(File input) {
    //     List<String> result = []
    //
    //     def xml = new XmlSlurper().parseText(input.text)
    //     xml.executionresult.each{ it ->
    //         String url = it.@href
    //         result << url.substring(url.lastIndexOf(":")+1);
    //     }
    //     return result
    // }
    // private List<String> parseTestSuiteTasksIds(File input) {
    //     List<String> result = []
    //
    //     def xml = new XmlSlurper().parseText(input.text)
    //     xml.tasks.each{ it ->
    //         result <<  it.@href
    //     }
    //     return result
    // }
}
