/*
 * Licensed Materials - Property of HCL
 * UrbanCode Deploy
 * (c) Copyright HCL Technologies Ltd. 2019. All Rights Reserved.
 */
package com.urbancode.urelease.integration.xldeploy

import com.urbancode.air.AirPluginTool
import com.urbancode.air.XTrustProvider
import com.urbancode.release.rest.framework.Clients
import com.urbancode.release.rest.models.internal.Comment
import com.urbancode.release.rest.models.internal.TaskExecution
import com.urbancode.urelease.integration.xldeploy.http.UCRClient
import com.urbancode.urelease.integration.xldeploy.http.XLRestClient
import com.urbancode.urelease.integration.xldeploy.models.PluginContext
import com.urbancode.urelease.integration.xldeploy.models.Target
import com.urbancode.release.rest.models.internal.ScheduledDeployment
import com.urbancode.release.rest.models.internal.ApplicationEnvironment
import com.urbancode.release.rest.models.Version;
import com.urbancode.release.rest.models.Inventory;
import org.apache.log4j.Logger
import groovy.json.JsonSlurper
import groovy.json.JsonOutput

import com.google.gson.Gson

class TaskExecutor extends IntegrationBase {
    PluginContext context
    String userId

    public TaskExecutor(Properties props) {
        super(props)

        /* Deserialize extraProperties JSON into objects */
        String extraProps = props['extraProperties']
        context = deserializeProps(extraProps)
        userId = context.userId
    }

    /**
     * Create a new task execution in UCR. The list of XL Deploy tasks for this execution
     * are stored in the xlTaskId property on the task execution itself.
     */
    public TaskExecution executeTask() {
        init() // Load the integration provider
        TaskExecution taskExecution = new TaskExecution()
        taskExecution.id(context.task.id)
        String versionRef = context.task.version.externalUrl
        String userId = context.userId

        List<String> xlTasks = new ArrayList<String>()
        List<Target> targets = context.task.targets

        if (targets.size() == 0) {
            postComment(taskExecution, "No targets selected for task execution.")
        }

        for (Target target : targets) {
            String envRef = target.externalUrl
            String xlTaskId = xlClient.createDeployTask(envRef, versionRef)

            postComment(taskExecution, "Starting XL Deploy task with ID ${xlTaskId}.")
            xlClient.startTask(xlTaskId)
            xlTasks.add(xlTaskId)
        }

        /* Save task IDs in the task execution */
        taskExecution.property("xlTaskIds", xlTasks.join(",")).save()
        return taskExecution
    }

    /**
     * Deserialize a JSON string into a PluginContext object.
     * @param props
     * @return An object containing all properties within the plugin context.
     */
    public PluginContext deserializeProps(String props) {
        Gson gson = new Gson()

        if (props) {
            return gson.fromJson(props, PluginContext.class)
        }
        else {
            throw new RuntimeException("Plugin context object (extraProperties) is empty.")
        }
    }

    /**
     * Post a comment on a task execution with a given user.
     * @param taskExecution
     * @param message
     */
    public void postComment(TaskExecution taskExecution, String message) {
        new Comment().userId(userId).task(taskExecution).comment(message).post()
    }
}
