/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* (c) Copyright IBM Corporation 2012, 2014. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
import java.io.IOException;
import javax.ws.rs.core.UriBuilder;
import com.urbancode.air.*
import com.urbancode.ubuild.codestation.client.*
import com.urbancode.commons.httpcomponentsutil.HttpClientBuilder
import com.urbancode.commons.util.IO;
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpGet
import org.apache.http.HttpStatus;
import org.apache.http.impl.client.DefaultHttpClient

import org.apache.log4j.BasicConfigurator
import org.apache.log4j.ConsoleAppender
import org.apache.log4j.Level
import org.apache.log4j.Logger
import org.apache.log4j.PatternLayout

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;

BasicConfigurator.resetConfiguration()
Logger.getRootLogger().setLevel(Level.ERROR)
Logger.getRootLogger().addAppender(new ConsoleAppender(new PatternLayout("%m%n")))
Logger.getLogger("com.urbancode.ubuild.codestation").setLevel(Level.DEBUG)
Logger.getLogger("com.urbancode.vfs.client").setLevel(Level.INFO)

final def javaHome                  = System.getenv('JAVA_HOME')
final def webUrl                    = System.getenv('WEB_URL')
final def authToken                 = System.getenv('AUTH_TOKEN')
final def buildLifeId               = System.getenv('BUILD_LIFE_ID')
final def pluginHome                = System.getenv("PLUGIN_HOME")

final def apTool                    = new AirPluginTool(this.args[0], this.args[1])
final def workDir                   = new File('.').canonicalFile
final def javaFile                  = new File(new File(javaHome), 'bin/java' + (apTool.isWindows ? '.exe' : ''))
final def udClientJarFile           = new File(new File(pluginHome), 'lib/udclient.jar')
final def CommandHelper cmdHelper   = new CommandHelper(workDir);

final def props                     = apTool.getStepProperties()
String url                          = props['automation/url']
def user                            = props['automation/user']
def ucdAuthToken                    = props['automation/authToken']
def password                        = props['automation/passScript']?.trim() ?: props['automation/password']
def ucdVersionSelection             = props['automation/ucdVersionSelection']
def componentName                   = props['componentName'];
def versionName                     = props['versionName'];
def description                     = props['versionDesc'];
def propertiesTextArea              = props['propertiesTextArea'];

if (ucdAuthToken) {
	user = "PasswordIsAuthToken"
	password = "{ \"token\" : \"${ucdAuthToken}\" }"
}

HttpClientBuilder clientBuilder = new HttpClientBuilder();
clientBuilder.setTrustAllCerts(true);
clientBuilder.setUsername(user);
clientBuilder.setPassword(password);
def udHttpClient = clientBuilder.buildClient();

// Try to create the version
cmdHelper.ignoreExitValue(true);
def cmdArgs = [javaFile.absolutePath, '-jar', udClientJarFile.absolutePath,
    "--weburl", url,
    "createVersion",
    "--component", componentName,
    "--name", versionName];

if (ucdAuthToken) {
    cmdArgs << "--authtoken" << ucdAuthToken
}
else {
    cmdArgs << "--username" << user << "--password" << password
}

if (description) {
    cmdArgs << '--description'
    cmdArgs << description
}

def versionId = null;
def createVersionOutput = null
int exitCode = cmdHelper.runCommand("Creating IBM UrbanCode Deploy Component Version", cmdArgs) { Process proc ->
    proc.out.close() // close stdin
    proc.consumeProcessErrorStream(System.out) // forward stderr
    createVersionOutput = proc.text.trim();
};
// Only try to parse as JSON if there was no error
if (exitCode == 0) {
    def versionJson = new JSONObject(createVersionOutput);
    versionId = versionJson.getString("id");
}
if (versionId) {
    println "Created version ${versionName} on component ${componentName} with id ${versionId}"
 
    apTool.setOutputProperty("buildlife/udeploy.versionId", versionId)
    apTool.setOutputProperties()
}

if (propertiesTextArea) {
    def httpHelper = new HttpHelper()
    if (user && password) {
        httpHelper.setUsernameAndPassword(user, password)
    }
    def propsHelper = new PropsHelper(httpHelper)
    propsHelper.setComponentVersionProperties(url, componentName, versionName, propertiesTextArea)
}

// get the component repository id
def repositoryId = ''
if ("6.0".equals(ucdVersionSelection)) {
	def componentUrl =
	    UriBuilder.fromPath(url).segment("rest", "deploy", "component", componentName).build().toString()
	HttpGet getComponentMethod = new HttpGet(componentUrl);
	try {
	    def httpResponse = udHttpClient.execute(getComponentMethod);
	    def code = httpResponse.getStatusLine().getStatusCode();
	    def content = httpResponse.getEntity().getContent();
	
	    switch (code) {
	        case HttpStatus.SC_OK:
	            String body = IO.readText(content);
	            JSONObject json = new JSONObject(body)
	            JSONArray componentProps = json.getJSONArray('properties')
	            for (int i=0; i<componentProps.length(); i++) {
	                JSONObject componentProp = componentProps.getJSONObject(i)
	                if ('code_station/repository'.equals(componentProp.getString('name'))) {
	                    repositoryId = componentProp.getString('value')
	                    break;
	                }
	            }
	            break;
	
	        case HttpStatus.SC_NOT_FOUND:
	            throw new Exception("Component not found: " + componentUrl);
	
	        case HttpStatus.SC_INTERNAL_SERVER_ERROR:
	            throw new Exception("Server error getting component: " + IO.readText(content));
	
	        default:
	            throw new Exception("Unexpected response from server: " + code);
	    }
	}
	finally {
	    getComponentMethod.releaseConnection();
	}
	
	if (!repositoryId) {
	    throw new Exception("Unable to retrieve repository id from the component.")
	}
}

// copy artifacts
try {
    def csCredentials = AuthenticationCredentials.createAuthTokenCredentials(authToken)
    def codestationBaseUrl = webUrl.endsWith("/") ? webUrl + "rest2" : webUrl + "/rest2"
    def codestationClient = new CodestationClient(codestationBaseUrl, csCredentials)
    def buildLife = codestationClient.buildLifeLookup.findBuildLife(buildLifeId)
    println "Initiating copy build life ${buildLifeId} artifacts to ${url}"
	if ("6.0".equals(ucdVersionSelection)) {
		def targetUrl = UriBuilder.fromPath(url).path('vfs').build().toString()
		codestationClient.copyAllArtifacts(buildLife, targetUrl, repositoryId, user, password, null, versionName)
	}
	else {
		codestationClient.copyAllArtifactsToUrbanCodeDeploy(buildLife, url, componentName, user, password, null, versionName)
	}
    println "Artifacts copied"
}
catch (Exception e) {
    println "Artifact copy failed"
    e.printStackTrace()
    System.exit(1)
}