#!/usr/bin/env groovy
/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Release
* (c) Copyright IBM Corporation 2011, 2013. All Rights Reserved.
* (c) Copyright HCL Technologies Ltd. 2020. All Rights Reserved.
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
import com.urbancode.air.*

import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Date;

import com.urbancode.urelease.rest.Rester;
import com.urbancode.release.rest.models.Application;
import com.urbancode.release.rest.models.Component;
import com.urbancode.release.rest.models.ComponentVersion;
import com.urbancode.release.rest.models.internal.ApplicationEnvironment;
import com.urbancode.release.rest.models.Version;
import com.urbancode.urelease.integration.deploy.AnsibleEntityFactory;
import com.urbancode.release.rest.models.internal.Comment;
import com.urbancode.release.rest.models.internal.TaskExecutionUpdate;
import com.urbancode.release.rest.models.internal.PluginIntegrationProvider;
import com.urbancode.release.rest.models.internal.TaskExecution;
import com.urbancode.release.rest.models.internal.Status;
import com.urbancode.release.rest.models.internal.VersionStatus
import com.urbancode.release.rest.models.internal.TaskPlan;
import com.urbancode.urelease.integration.models.Inventory;
import com.urbancode.release.rest.framework.Clients;
import java.net.SocketTimeoutException;
import com.urbancode.urelease.integration.models.Job_Template;
final def workDir = new File('.').canonicalFile

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

//We launch the integration here
def integration = new DeployIntegration (props)

def totalStart = System.currentTimeMillis()
//We authenticate with IBM UrbanCode Release
integration.releaseAuthentication ()
//We launch the full Integration
integration.runIntegration ()
def totalEnd = System.currentTimeMillis()

public class DeployIntegration {

    def releaseToken;
    def fullIntegration;
    def serverUrl;
    def deployHostName;
    def deployToken;
    def integrationProviderVersion
    def integrationProviderId;
    def entityFactory;
    def provider;
    def currentDeployServerTime;
    def lastExecutionTime;
    def defaultTimeout;

    //Main constructor
    DeployIntegration (props) {
        //Release Token used for Authentication
        this.releaseToken = props['releaseToken'];
        //Delta Sync or Full Sync
        this.fullIntegration = props['fullIntegration'];
        //Release Server URL
        this.serverUrl = props['releaseServerUrl'];
        //Deploy info
        this.deployHostName = props['deployHostName']
        this.deployToken = props['deployToken']
        
        //Timeout to connect to UCR and UCD
        this.defaultTimeout = props['timeout'];
        
        //Integration Provider currently running that Integration
        this.integrationProviderId = props['releaseIntegrationProvider'];
        
        //If no value is set for the timeout then we set it to 0
        if (defaultTimeout == null || defaultTimeout == "") {
            defaultTimeout = 0;
        }
        else {
            try {
                defaultTimeout = Integer.parseInt(defaultTimeout);
                println("Timeout for http requests is set to "+defaultTimeout+"s ")
                //We convert it into milliseconds
                defaultTimeout = defaultTimeout * 1000;
            }
            catch (Exception ex) {
                printLog("WARNING", "The default timeout provided ("+defaultTimeout+") is not a number and no timeout will be set")
                defaultTimeout = 0;
            }
        }
    }

    //--------------------------------------------------------------
    //Authentication with Release
    def releaseAuthentication () {
        Clients.loginWithToken(serverUrl, releaseToken, defaultTimeout);
    }

    //--------------------------------------------------------------
    def runIntegration () {
        println "------------------------------------------------------------------------------------------------------------------------------"
        //We load the Integration Provider Info
        provider = new PluginIntegrationProvider().id(integrationProviderId).get()

        //We get the last execution date (UCD time)
        def lastExecutionDeployDate = null;
        this.entityFactory = new AnsibleEntityFactory(deployHostName, deployToken,defaultTimeout);
        
        entityFactory.setProvider(provider);
        
        println "---------------------------------------------------------------------------------------------------------------"
        List<Inventory> inventories = importInventories();
        println("inventories imported: "+inventories.size())
        //Import Job Templates from UCD
        currentDeployServerTime = System.currentTimeMillis();
        importJobTemplates (inventories);
        
        importWorkFlowJobTemplates (inventories);
        
        provider.property("fullIntegration", "false").property("lastExecutionDeployTime", String.valueOf(currentDeployServerTime)).put()
        new TaskPlan().syncDeleted(provider)
    }
    
    def importWorkFlowJobTemplates(List<Inventory> inventories) {
        println "<b><u>>>>> Import WorkFlow Job Templates</u></b>"
        def pageSize = 100;
        def pageNo = 1;
        entityFactory.syncWorkFlowJobTemplate(inventories);
    }

    //--------------------------------------------------------------
    def importJobTemplates (List<Inventory> inventories) {
       println "<b><u>>>>> Import Job Templates</u></b>"
       def pageSize = 100;
       def pageNo = 1;
       entityFactory.syncJobTemplate(inventories);
    }
    def importInventories () {
        println "<b><u>>>>> Import Inventories</u></b>"
        def pageSize = 100;
        def pageNo = 1;
        return entityFactory.getInventories();
     }


    //--------------------------------------------------------------
    //Method that replaces the white spaces on versions name with an underscore
    def handleTrailingWhiteSpace(s) {
        if(s.endsWith(" ") || s.endsWith("_")) {
            println "Trailing whitespace in name: " + s;
            s = s + "_"
        }
        return s;
    }

    //--------------------------------------------------------------
    //Print logs
    def printLog(type, message) {
        println "<span class=\""+type+"\">"+message+"</span>"
    }
}
