/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2002, 2013. 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.integration

import com.urbancode.air.plugin.rtcworkitems.RTCWorkItemHelper
import com.urbancode.commons.httpcomponentsutil.HttpClientBuilder
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpPost
import org.apache.http.client.methods.HttpRequestBase
import org.apache.http.entity.StringEntity

public class CreateWorkItem {

    String url
    String password
    String username
    String projectName
    String comment
    String workItemType
    String workItemSummary
    String filedAgainst
    String additionalAttributes
    String procId
    String compProcId
    String appProcId
    String requestId
    String serverUrl
    boolean addCommentUrl
    def props

    public void execute() {
        createWorkItem()
    }

    public void createWorkItem() {

        HttpClientBuilder builder = new HttpClientBuilder()
        builder.setTrustAllCerts(true)
        HttpClient client = builder.buildClient()

        def rtcHelper = new RTCWorkItemHelper(props)
        def catalogurl = rtcHelper.getCatalogUrl(client)
        rtcHelper.authenticateRTCUser(catalogurl, client)
        def servicesUrl = rtcHelper.getServicesUrl(catalogurl, client)
        def contextId = servicesUrl?.split("/")[-3]
        System.out.println("Context ID: " + contextId)
        def workItemTypeId = rtcHelper.getWorkItemTypeId(workItemType, contextId, client)
        def filedAgainstID
        if (filedAgainst && filedAgainst.trim().length() > 0) {
            filedAgainstID = rtcHelper.getFiledAgainstId(filedAgainst, contextId, client)
        }
        def workItemCreateUrl = rtcHelper.getWorkItemCreationUrl(workItemTypeId, servicesUrl, client)


        def attributes
        if (additionalAttributes && additionalAttributes.trim().length() > 0 && additionalAttributes.indexOf("=") > 0) {
            attributes = additionalAttributes.trim().split("\r|\n|\r\n")?.findAll{ it -> it && it.trim().length() > 0 && it.indexOf("=") > 0}
        }

        HttpRequestBase method = null
        def response = null
        def createResult
        def gBuilder = new groovy.xml.StreamingMarkupBuilder()

        def newWorkItem = {
            mkp.declareNamespace('oslc_cm':'http://open-services.net/xmlns/cm/1.0/')
            mkp.declareNamespace('rtc_cm':'http://jazz.net/xmlns/prod/jazz/rtc/cm/1.0/')
            mkp.declareNamespace('dc': 'http://purl.org/dc/terms/')
            mkp.declareNamespace('rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#')
            mkp.declareNamespace('calm': 'http://jazz.net/xmlns/prod/jazz/calm/1.0/')
            mkp.declareNamespace('oslc_pl': 'http://open-services.net/ns/pl#')
            'oslc_cm:ChangeRequest'{
                if (filedAgainstID) {
                    'rtc_cm:filedAgainst'('rdf:resource':"$filedAgainstID")
                }

                'dc:title'(workItemSummary)

                if (attributes && attributes.size() > 0) {
                    attributes.each {
                        def key = it.split("=")[0]?.trim()
                        def value = it.split("=")[1]?.trim()
                        "rtc_cm:$key"(value)
                    }
                }
            }
        }

        println "Creating work item ..."
        gBuilder.encoding = "UTF-8"
        def workItemId
        //post the new work item
        try {
            method = new HttpPost(workItemCreateUrl)
            String newCommentString = gBuilder.bind(newWorkItem)
            method.setEntity(new StringEntity(newCommentString))
            method.setHeader("Accept", "application/x-oslc-cm-change-request+xml")
            method.setHeader("Content-type", "application/x-oslc-cm-change-request+xml")
            createResult = client.execute(method)
            int statusCode = createResult.getStatusLine().getStatusCode()
            if (statusCode < 300 && statusCode >= 200) {
                def resp = createResult.getEntity().getContent()

                try {
                    def respXml = new XmlParser().parse(resp)
                    workItemId = respXml['dc:identifier']?.text()
                }
                catch (Exception e) {
                    System.out.println(resp)
                    throw e
                }
                println "Successfully created work item $workItemId"
            }
            else {
                println "Failed to create work item"
                println createResult.getEntity().getContent().text
                throw new Exception ("[Error] Failed to create work item: \n createResult.getEntity().getContent().text")
            }
        }
        finally {
            if (method != null) {
                method.releaseConnection()
            }
        }

        if(comment && comment.trim().length() > 0) {
            AddComment ac = new AddComment()
            ac.url = url
            ac.username = username
            ac.password = password

            ac.projectName = projectName
            ac.workItemId = workItemId
            ac.comment = comment
            ac.props = props
            ac.requestId = requestId
            ac.appProcId = appProcId
            ac.compProcId = compProcId
            ac.procId = procId
            ac.addCommentUrl = addCommentUrl
            ac.serverUrl = serverUrl

            ac.execute()
        }
    }
}
