package com.urbancode.air.plugin.automation;

import org.apache.commons.codec.*
import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.*
import org.apache.http.HttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.StringEntity

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

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

    //**************************************************************************
    // INSTANCE
    //**************************************************************************
    
    String projectKey
    String requirementKey
    String defectName
    String defectDesc
    String priority
    String severity
    String state
    String submitter
    String environment
    String build
    
    public void execute() {
        setupHttpClient()
        
        createDefect()
    }
    
    private void createDefect() {
        def workspaceRef = configureWorkspace()
        
        def projId
        def reqId
        
        if (projectKey && projectKey.length() > 0) {
          def projectMethod = new HttpGet(url + "project?workspace=" + URLEncoder.encode(workspaceRef, "UTF-8") + "&query=" +
              URLEncoder.encode("(Name = \"" + projectKey + "\")" ,"UTF-8") + "&" + URLEncoder.encode("fetch", "UTF-8") + "=" +
                  URLEncoder.encode("true", "UTF-8"))
          HttpResponse response = client.execute(projectMethod)
          
          String responseText = IO.readText(response.entity.content)
          projId = new XmlParser().parseText(responseText).Results.Object.ObjectID[0].text()
          if (projectMethod != null) {
             projectMethod.releaseConnection()
          }
        }
        else {
          def requirementMethod = new HttpGet(url + "hierarchicalrequirement?workspace=" + URLEncoder.encode(workspaceRef, "UTF-8") +
              "&query=" + URLEncoder.encode("(FormattedID = " + requirementKey + ")" ,"UTF-8") + "&" + URLEncoder.encode("fetch", "UTF-8") +
                  "=" + URLEncoder.encode("true", "UTF-8"))
          HttpResponse response = client.execute(requirementMethod)
          
          String responseText = IO.readText(response.entity.content)
          reqId = new XmlParser().parseText(responseText).Results.Object.ObjectID[0].text()
          projId = new XmlParser().parseText(responseText).Results.Object.Project.'@ref'[0]
          if(requirementMethod != null) {
             requirementMethod.releaseConnection()
          }
        }
        // Generate XML doc
        def writer = new StringWriter()
        def builder = new groovy.xml.MarkupBuilder(writer)
        builder.Defect(){
          Project(projId)
          if (requirementKey && requirementKey.length() >0) {
            Requirement(reqId)
          }
          Description(defectDesc)
          Name(defectName)
          Priority(priority)
          Severity(severity)
          State(state)
          Owner(submitter)
          Environment(environment)
          FoundInBuild(build)
          //Workspace(workspaceRef)
        }
        
        HttpPost method = new HttpPost(url + "defect/create")
        method.setEntity(new StringEntity(writer.toString(), null, null));
        def result = client.execute(method)
        def response = IO.readText(result.entity.content)
        
        //check results
        def createResult = new XmlParser().parseText(response);
        def errors = createResult.Errors.OperationResultError.size();
        def warnings = createResult.Warnings.OperationResultWarning.size();
        
        if (errors == 0 && warnings == 0) {
          println "Successfully created defect! ObjectRef =" + createResult.Object.'@ref';
          System.exit 0
        }
        else {
          println "ERROR!!! Rally Server could not create defect! "
          createResult.Errors.OperationResultError.each { println it.text() }
          createResult.Warnings.OperationResultWarning.each { println it.text() }
          System.exit 1
        }
    }
}