package com.urbancode.air.plugin.automation

import com.urbancode.air.http.*
import groovy.xml.XmlUtil
import org.jsoup.Jsoup;

public class QCPublishBugReport extends AutomationBase {
    
    def bugPattern
    def failMode
    
    private def bugIdSet = [] as Set
    private def artifactIdToChangeSetListMap = [:]
    private def bugIdAndChangeIds = ""
    private def outputFileName
    private def outputFile
    
    public void execute() {
        init()
        
        def changesXml = HttpHelper.getChangeSets()
        parseChangeSets(changesXml)

        if (!bugIdSet) {
            println 'No defects found in source changes!'
        }
        else {
            uploadBugReport()
            
            try {
                def url = generateUrl()
                HttpHelper.sendPostRequest(url, outputFile)
            }
            finally {
                outputFile.delete()
            }
        }
    }
    
    private def parseChangeSets(def changesXml) {
        def pattern = java.util.regex.Pattern.compile(bugPattern)
        new XmlSlurper().parseText(changesXml)."change-set".each { changeSetElem ->
        
            def matcher = pattern.matcher(changeSetElem.comment.text());
            while (matcher.find()) {
                def bugId
                if (matcher.groupCount() > 0 ) {
                    // they specified a '(...)' group within the pattern, use that as the bug-id
                    bugId = matcher.group(1)
                }
                else {
                    // use the whole matching substring as the bug-id
                    bugId = matcher.group()
                }
        
                println("Found defect identifier in change comment: $bugId")
                bugIdSet << bugId
                def changeSetList = artifactIdToChangeSetListMap[bugId]
                if (!changeSetList) {
                    changeSetList = []
                    artifactIdToChangeSetListMap[bugId] = changeSetList
                }
                changeSetList << changeSetElem."change-id".text()
            }
        }
        println 'Completed reading source changes.'
    }
    
    private uploadBugReport() {
        bugIdSet.each() { bugId ->
            if (bugIdAndChangeIds) {
                bugIdAndChangeIds += ","
            }
            def changeId = artifactIdToChangeSetListMap.get(bugId).get(0)
            bugIdAndChangeIds += bugId + "|" + changeId
        }

        def command = generateCommand()
        runCommand("Retrieving Bug Details", command)
        
        outputFile = new File(outputFileName)
        
        // read file and rewrite the description without HTML
        def issuesXml = new XmlParser().parse(outputFile)
        def descriptions = issuesXml.depthFirst().findAll { it.name() == 'description' }
        println "Found ${descriptions.size()} descriptions"
        descriptions.each { description ->
            description.value = Jsoup.parse(description.text()).text()
        }
        
        outputFile.delete()
        outputFile << XmlUtil.serialize(issuesXml)
    }
    
    private def generateCommand() {
        outputFileName = ".bugDetails.xml"
        def getBugDetailsCommand = [cscriptExe]
        getBugDetailsCommand << PLUGIN_HOME + "\\qc_get_bug_details.vbs"
        getBugDetailsCommand << serverUrl
        getBugDetailsCommand << username
        getBugDetailsCommand << password
        getBugDetailsCommand << domain
        getBugDetailsCommand << project
        getBugDetailsCommand << bugIdAndChangeIds
        getBugDetailsCommand << outputFileName
        
        return getBugDetailsCommand
    }
    
    private def generateUrl() {
        String buildLifeId = System.getenv("BUILD_LIFE_ID")
        
        // construct the URL with property replacements
        String baseUrl = System.getenv("WEB_URL")
        baseUrl += baseUrl.endsWith("/") ? "" : "/"
        
        String url = baseUrl + "rest/buildlife/${buildLifeId}/issues"

        return url
    }
}