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

import java.util.Map;
import org.codehaus.jettison.json.JSONObject;
import org.codehaus.jettison.json.JSONArray;

import com.urbancode.air.AirPluginTool;

import groovy.io.FileType
import com.urbancode.ud.client.UDRestClient;
import com.urbancode.ud.client.ResourceClient;

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

def MAX_RETRIES = 3;

def weburl = System.getenv("AH_WEB_URL");
def user = apTool.getAuthTokenUsername();
def password = apTool.getAuthToken();
def finalURI = new URI(weburl);
def udClient = new ResourceClient(finalURI, user, password);

def server = props['server'].trim();
def serverCleaned = server.replaceAll('https*://', '').replaceAll('/', '');
def roleName = "KubernetesCluster";

def getOrCreateSubResource = { resourcePath, parentUUID, description ->
    def resourceName = resourcePath.substring(resourcePath.lastIndexOf("/") + 1);
    def resource = null;
    def tries = 0;
    def done = false;
    while (!done && tries < MAX_RETRIES) {
        try {
            try {
                resource = udClient.getResourceByPath(resourcePath);
            }
            catch (IOException e) {
                //resource does not exist(i hope)
                resource = null;
            }
            if (resource == null) {
                def nodeId = udClient.createSubResource(parentUUID, resourceName, description);
                resource = udClient.getResourceByPath(resourcePath);
            }
            done = true;
        }
        catch (IOException e) {
            tries++;
            done = false;
            println("Got IOException in getOrCreateSubResource for ${resourcePath}");

            if (tries < MAX_RETRIES) {
                println ("Retrying...")
            }
            else {
                throw e;
            }
        }
    }

    return UUID.fromString(resource.getString("id"));
}

def addRoleToResource = { resource, role, properties ->
    def tries = 0;
    def done = false;
    while (!done && tries < MAX_RETRIES) {
        try {
            udClient.setRoleOnResource(resource.toString(), role, properties);
            done = true;
        } catch (IOException e) {
            tries++;
            done = false;
            println("Got IOException in addRoleToResource for ${resource}");
            if (tries < MAX_RETRIES) {
                println ("Retrying...")
            } else {
                throw e;
            }
        }
    }
}

def clusterProps = new HashMap<String, String>();
clusterProps.put("kubernetes.server", server);
clusterProps.put("kubernetes.username", props['username']?.trim());
clusterProps.put("kubernetes.password", props['password']?.trim());
clusterProps.put("kubernetes.token", props['token'].trim());
clusterProps.put("kubernetes.namespace", props['namespace'].trim());
clusterProps.put("kubernetes.kubeconfig", props['kubeconfig'].trim());
clusterProps.put("kubernetes.cluster", props['cluster'].trim());
clusterProps.put("kubernetes.context", props['context'].trim());
clusterProps.put("kubernetes.user", props['user'].trim());
clusterProps.put("kubernetes.allowInsecure", props['allowInsecure'].trim());
clusterProps.put("kubernetes.certificateAuth", props['certificateAuth'].trim());
clusterProps.put("kubernetes.clientCertificate", props['clientCertificate'].trim());
clusterProps.put("kubernetes.clientKey", props['clientKey'].trim());

def rootResource = udClient.getResourceByPath(props['parentResource'].trim());
def rootResourceIdString = rootResource.getString("id");
def rootResourceId = UUID.fromString(rootResourceIdString);

def resourcePath = rootResource.path + "/" + roleName + " - " + serverCleaned;
def description = "Kubernetes cluster resource for " + server;
def clusterResource = getOrCreateSubResource(resourcePath, rootResourceId, description);
addRoleToResource(clusterResource, roleName, clusterProps);

apTool.setOutputProperty("resourcePath", resourcePath);
apTool.setOutputProperties();
