/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* IBM UrbanCode Deploy
* IBM UrbanCode Release
* IBM AnthillPro
* (c) Copyright IBM Corporation 2002, 2016. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/

import org.apache.http.message.BasicNameValuePair

import com.urbancode.air.AirPluginTool
import com.urbancode.air.plugin.automation.RallyHelper

// Get step variables
AirPluginTool apTool = new AirPluginTool(this.args[0], this.args[1])
Properties inProps = apTool.getStepProperties()

String rallyUrl    = inProps['rallyUrl']
String rallyVer    = inProps['rallyVer']
String workspace   = inProps['workspace']
String rallyUser   = inProps['rallyUser']
String rallyPass   = inProps['rallyPass']
String rallyApiKey = inProps['rallyApiKey']
String proxyHost   = inProps['proxyHost']
String proxyPort   = inProps['proxyPort']
String proxyPass   = inProps['proxyPass']
String proxyUser   = inProps['proxyUser']

String artifactKey  = inProps['artifactKey']
String type         = inProps['type']
String property     = inProps['property']
String newValue     = inProps['newValue']

// Set up RallyHelper
RallyHelper.setupHttpClient(rallyApiKey, rallyUser, rallyPass, proxyHost, proxyPort, proxyUser, proxyPass)
String workspaceRef = RallyHelper.configureWorkspace(rallyUrl, rallyVer, workspace)

// Change all artifact properties
int successfulChanges = 0
ArrayList<String> artifacts = RallyHelper.makeList(artifactKey)
ArrayList<String> newValues = RallyHelper.makeList(newValue)
if (newValues.size() != 1 && artifacts.size() != newValues.size()) {
    println ('[error]  Size mismatch between artifacts and properties.')
    println ('[possible solution]  Please update the step configuration property Property to either have a single value for ' +
             "all artifacts or a comma-separated list of ${artifacts.size()} Properties to match the number of Artifacts.")
    System.exit(1)
}
artifacts.eachWithIndex { artifact, index ->
    println ("\n----- Working on artifact ${index + 1} / ${artifacts.size()} -----")
    def currentNewVal
    if (newValues.size() == 1) {
        currentNewVal = newValues[0]
    }
    else {
        currentNewVal = newValues[index]
    }
    if (changeArtifactProperty(workspaceRef, rallyVer, artifact, type, property, currentNewVal)) {
        successfulChanges++
    }
}

println ("\n\n----- Summary: ${successfulChanges} / ${artifacts.size()} artifact properties successfully changed -----")
if (successfulChanges == artifacts.size()) {
    println ('[ok] All properties changed successfully.')
    System.exit(0)
}
else {
    println ('[error] Not all properties changed.')
    System.exit(1)
}

/**
*  @param workspaceRef The url reference for the workspace
*  @param version The version of the Rally Server
*  @param artifact The ID of the artifact
*  @param aType The type of the artifact
*  @param aProperty The property of the artifact to update
*  @param newValue The new value to set the artifact property to
*  @return True if the artifact property was successfully changed, false if not
*/
private boolean changeArtifactProperty(String workspaceRef, String version, String artifact, String aType, String aProperty, String newValue) {
    // Get artifact ObjectID
    println ("\n[action] Retrieving ObjectID for artifact ${artifact}...")
    List<BasicNameValuePair> queryParams = new LinkedList<BasicNameValuePair>()
    queryParams.add(new BasicNameValuePair('workspace', workspaceRef))
    queryParams.add(new BasicNameValuePair('query', "(FormattedID = ${artifact})"))
    queryParams.add(new BasicNameValuePair('fetch', 'true'))
    String getBody = RallyHelper.executeHttpGet(aType, queryParams)

    def artifactId = RallyHelper.getElement(getBody, 'Results.Object.ObjectID', 'QueryResult.Results.ObjectID')
    if (artifactId) {
        println ("[ok]  artifactId found: ${artifactId}")
    }
    else {
        println ('[error]  Could not determine artifactId')
        System.exit(1)
    }

    // Generate POST content
    HashMap<String, String> children = new HashMap<String, String>()
    children.put(aProperty, newValue)
    String updateInfo = RallyHelper.buildPost(aType, children)

    // Change artifact property
    println ("\n[action] Changing property ${aProperty} for artifact ${artifact} to ${newValue}...")
    String postBody = RallyHelper.executeHttpPost(aType + '/' + artifactId, updateInfo)

    // Print errors and warnings
    println ('\n[action] Checking response from Rally Server...')
    RallyHelper.printWarngingsAndErrors(postBody, 'Operation')

    // Verify change
    println ('\n[action] Verifying changed state...')
    getBody = RallyHelper.executeHttpGet(aType + '/' + artifactId)
    def actualValue = RallyHelper.getElement(getBody, aProperty, "${aType}.${aProperty}")

    // check success
    if (actualValue.equals(newValue)) {
        println ("[ok] Successfully updated artifact property ${aProperty} to ${actualValue}")
        return true
    }
    else {
        println ("[error] Artifact property ${aProperty} did not update correctly, still ${actualValue}")
        return false
    }
}
