import com.urbancode.air.*;
import com.urbancode.air.plugin.automation.*;
import java.lang.reflect.Array;

XTrustProvider.install();

final File resourceHome = new File(System.getenv()['PLUGIN_HOME'])
final def buildLifeId = System.getenv()['BUILD_LIFE_ID']

final def apTool = new AirPluginTool(this.args[0], this.args[1])
final def props = apTool.getStepProperties()

final def serverUrl       = props['automation/serverUrl']
final def serverVersion   = props['automation/serverVersion']
final def username        = props['automation/username']
final def password        = props['automation/passwordScript'] ?: props['automation/password']

final def statusName = props['statusName']
final def issueIdPattern  = props['issueIdPattern']
final def failMode        = FailMode.valueOf(props['failMode']);

//------------------------------------------------------------------------------
// Script content
//------------------------------------------------------------------------------

println "Server:\t$serverUrl";
println "Status:\t$statusName";
println "Issue Keys:\t$issueIdPattern";

// Load the appropriate Jira Soap Classes into classloader
final def jiraSoapJar = new File(resourceHome, "jira-${serverVersion}.wsdl.jar")
assert jiraSoapJar.isFile();
this.class.classLoader.rootLoader.addURL(jiraSoapJar.toURL())
def JiraSoapServiceServiceLocator = Class.forName('com.atlassian.jira.rpc.soap.jirasoapservice_v2.JiraSoapServiceServiceLocator');
def RemoteIssue = Class.forName('com.atlassian.jira.rpc.soap.beans.RemoteIssue')
def RemoteComment = Class.forName('com.atlassian.jira.rpc.soap.beans.RemoteComment')
def RemoteFieldValue = Class.forName('com.atlassian.jira.rpc.soap.beans.RemoteFieldValue')
def RemotePermissionException = Class.forName('com.atlassian.jira.rpc.exception.RemotePermissionException')


def failures = 0;
def issueIdSet = [] as Set
// connect to Jira
String fullAddress = serverUrl + "/rpc/soap/jirasoapservice-v2";
if (!fullAddress.startsWith("http")) {
    fullAddress = "http://" + fullAddress;
}
def locator = JiraSoapServiceServiceLocator.newInstance();
locator.jirasoapserviceV2EndpointAddress = fullAddress;
def jiraSoapService = locator.getJirasoapserviceV2();
def sessionToken = jiraSoapService.login(username, password);
try {
    def statuses = jiraSoapService.getStatuses(sessionToken);
    XMLHelper helper = new XMLHelper(issueIdPattern)
    helper.getChangesets()
    issueIdSet = helper.getIssueIdSet()

    issueIdSet.each { issueKey ->
        try {
            def returnedIssue = jiraSoapService.getIssue(sessionToken, issueKey)
            if (!returnedIssue) {
                println("\tSkipping Issue "+issueKey+": Specified Issue not found.");
                failures++;
                if (failMode == FailMode.FAIL_FAST) {
                   throw new Exception("Issue not found for $issueKey");
                }
            }
            else {
                def status = returnedIssue.getStatus();
                for (def remoteStatus : statuses) {
                    if (remoteStatus.getId() == status) {
                         status = remoteStatus.getName();
                         break;
                    }
                }
                if (status != statusName) {
                    failures++;
                    println ("Issue $issueKey status : $status != $statusName");
                    if (failMode == FailMode.FAIL_FAST) {
                       throw new Exception("Issue $issueKey status $status != $statusName");
                    }
                }
                else {
                    println ("Issue $issueKey has correct status : $status");
                }
            }
        }
        catch (Exception e) {
            throw e;
        }
    }
}
finally {
    jiraSoapService.logout(sessionToken)
}
if (failMode == FailMode.FAIL_ON_ANY_FAILURE && failures > 0) {
    println "Got one or more failure!";
    throw new RuntimeException("Something Failed!");
}

if (failMode == FailMode.FAIL_ON_NO_UPDATES && failures == issueIdSet.size()) {
    println "All failed!";
    throw new RuntimeException("All Failed!");
}
