package com.urbancode.air.plugin.automation;

import com.urbancode.air.*
import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.auth.AuthScope;
import com.urbancode.commons.util.IO

public class ChangeArtifactProperty extends AutomationBase {
    
    //**************************************************************************
    // CLASS
    //**************************************************************************

    //**************************************************************************
    // INSTANCE
    //**************************************************************************
    
    String defectType
    String property
    String newValue
    String artifactKey
    
    public void execute() {
        setupHttpClient()
        
        if (artifactKey && artifactKey.trim().length() > 0) {
            updateProperty()
        }
        else {
            System.out.println 'No artifacts found to update!';
        }
    }
    
    private void updateProperty() {
        def workspaceRef = configureWorkspace()

        if(!newValue || newValue.trim().length() == 0) {
            newValue = "";
        }
        
        String[] newValArray = newValue.split(',');
        String[] artifactArray = artifactKey.split(',');
        if(newValArray.length != 1 &&
                newValArray.length != artifactArray.length) {
            println "The number of New Value items must be 1 or match the number of Artifacts!";
            System.exit(1);
        }
        
        def isError = false;
        for(int i = 0; i<artifactArray.length; i++) {
            def artifact = artifactArray[i];
            def newVal = newValArray.length == 1 ? newValArray[0] : newValArray[i];
            
            def writer = new StringWriter();
            def builder = new groovy.xml.MarkupBuilder(writer);
            def typeNode = builder.createNode(defectType);
            def propertyNode = builder.createNode(property, newVal);
            builder.nodeCompleted(typeNode, propertyNode);
            builder.nodeCompleted(null, typeNode);
            
            if (artifact.trim().length() > 0) {
                println url + defectType.toLowerCase() + "?workspace=" + URLEncoder.encode(workspaceRef, "UTF-8") +
                    "&query=" + URLEncoder.encode("(ObjectID = " + artifact.trim() + ")" ,"UTF-8") + "&" + URLEncoder.encode("fetch", "UTF-8") +
                        "=" + URLEncoder.encode("true", "UTF-8")
                //query to get objectId from formattedID
                HttpMethod queryMethod = new GetMethod(url + defectType.toLowerCase() + "?workspace=" + URLEncoder.encode(workspaceRef, "UTF-8") +
                    "&query=" + URLEncoder.encode("(ObjectID = " + artifact.trim() + ")" ,"UTF-8") + "&" + URLEncoder.encode("fetch", "UTF-8") +
                        "=" + URLEncoder.encode("true", "UTF-8"))
                def queryResult = client.executeMethod(queryMethod)
                //super cool xml parser to get the objectID of the first result(i love you groovy)
                String responseText = IO.readText(queryMethod.getResponseBodyAsStream())
                def queryResponse = new XmlParser().parseText(responseText).Results.Object.ObjectID[0].text()
    
                //post to update the object in question
                HttpMethod method = new PostMethod(url + defectType + "/" + queryResponse)
                method.setRequestEntity(new StringRequestEntity(writer.toString()));
                def result = client.executeMethod(method)
                def response = IO.readText(method.getResponseBodyAsStream())
    
                //check results
                def changeResult = new XmlParser().parseText(response);
                def errors = changeResult.Errors.OperationResultError.size();
                def warnings = changeResult.Warnings.OperationResultWarning.size();
    
                if(errors == 0 && warnings == 0 && result >=200 && result <300) {
                  System.out.println "Successfully updated item " + artifact;
                }
                else {
                  println "ERROR!!! Rally Server could not update item " + artifact;
                  println "Update XML was : " + writer.toString()
                  changeResult.Errors.OperationResultError.each { println it.text() }
                  changeResult.Warnings.OperationResultWarning.each { println it.text() }
                  isError = true
                }
            }
        }
        if(isError) {
            System.exit(1);
        }
    }
}