package com.urbancode.air.plugin.automation

import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.*
import org.apache.commons.httpclient.protocol.*
import org.apache.http.HttpResponse
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpGet

import com.urbancode.air.*
import com.urbancode.commons.httpcomponentsutil.HttpClientBuilder
import com.urbancode.commons.util.IO


public class AddComment extends AutomationBase {
    
    //*********************************************************************************************
    // CLASS
    //*********************************************************************************************
    
    //*********************************************************************************************
    // INSTANCE
    //*********************************************************************************************
        
    String workItemProperty = "workItems"
    String workItemRegex
    String comment
    
    public void execute() {
        String changeXml = getChangeSets()
        addComment(changeXml);
    }
    
    public void addComment(String changeXml) {
        try {
            def workItemMap = [:] as Map
            def workItems = []
            // get changeset info
            new XmlSlurper().parseText(changeXml)."change-set".each { element ->
                if (element.'properties'.size() > 0) {
                    element.'properties'.'property'.each {
                        if (workItemProperty.equalsIgnoreCase(it.'name'.text())) {
                            it.'value'.text().split(',').each { item ->
                                if (item.matches(workItemRegex)) {
                                    workItems << item
                                }
                            }
                        }
                    } 
                
                    workItems.each { item ->
                        def currentCommentSet = workItemMap[item]?:[] as Set
                        currentCommentSet << element.'comment'.text()
                        workItemMap.put(item, currentCommentSet)
                    }
                }
            }
        
            // now prepare tftool command
            if (workItemMap.size() > 0) {
                def hasError = false
                workItemMap.each {
                    if (comment) it.value.addAll(comment.split('\n'))
                    def exe = System.getenv("PLUGIN_HOME") + "${fileSep}lib${fileSep}tftool" + tfsVersion + ".exe"
                    def command = [exe, 'comment', "/server:$serverUrl"]
        
                    if (serverUserName && serverPassword) {
                        command << "/user:$serverUserName"
                        command << "/password:$serverPassword"
                    }
        
                    command << "/id:${it.key}"
                    command << "/comment:${it.value.join('<br>')}"
        
                    try {
                        new CommandHelper(workDir).runCommand('Adding Work Item Comment', command)
                    }
                    catch (Exception e) {
                        println e.message
                        hasError = true
                    }
                }
        
                if (hasError) {
                    println 'Got errors during work item comment updates!'
                    System.exit 1
                }
            }
            else {
                println 'Did not detect any work items in changelog!'
            }
        }
        catch (Throwable t) {
            t.printStackTrace()
            System.exit 1
        }
    }
    
    private String getChangeSets() {
        def authToken = System.getenv("AUTH_TOKEN")
        int buildLifeId = Integer.parseInt(System.getenv("BUILD_LIFE_ID"))
        String webUrl = System.getenv("WEB_URL")
        webUrl += webUrl.endsWith("/") ? "" : "/"
        
        String changesRequestUrl = webUrl + "rest/buildlife/${buildLifeId}/sourcechanges"
        
        println "Getting source changes from server"
        
        HttpGet getMethod = new HttpGet(changesRequestUrl)
        if (authToken) {
            getMethod.addHeader("Authorization-Token", authToken)
        }
        
        HttpClientBuilder builder = new HttpClientBuilder()
        builder.setTrustAllCerts(true)
        HttpClient client = builder.buildClient()
        
        HttpResponse response = client.execute(getMethod)
        def responseCode = response.statusLine.statusCode
        InputStream responseStream = response.entity.content
        
        String changesXml = IO.readText(responseStream)
        
        if (!isGoodResponseCode(responseCode)) {
            throw new Exception("Failed to get build life source changes from the server: $changesXml")
        }
        
        getMethod.releaseConnection()
        
        return changesXml
    }
    
    private boolean isGoodResponseCode(int responseCode) {
        return responseCode >= 200 && responseCode < 300;
    }
}