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

package com.urbancode.air.plugin.iisconfiguration.helper
import org.codehaus.jettison.json.JSONObject
import org.codehaus.jettison.json.JSONArray
import com.urbancode.air.plugin.iisconfiguration.helper.ResourceHelper
import com.urbancode.air.plugin.iisconfiguration.Globals

class TopologyDiscoveryHelper {
    def resourceHelper

    public TopologyDiscoveryHelper(ResourceHelper resourceHelper){
        this.resourceHelper = resourceHelper
    }

    //convert json to a properties map
    private jsonToPropMap (JSONObject jsonObj){
        def result = [:]
        jsonObj.keys().each{
            result[it] = jsonObj.get(it)
        }

        return result
    }

    //convert properties map into json
    private propMapToJson (propMap){
        JSONObject resourceRoleProps = new JSONObject()
        return propMap.each { key, value -> resourceRoleProps.put(key, value) }
    }

    //merge first jsonarray contents into the second one
    public mergeJSONArrays (JSONArray jsonArrayInput, JSONArray result){
        for (int i = 0; i < jsonArrayInput.length(); i++) {
            result.put(jsonArrayInput.get(i))
        }
        return result
    }

    //bundle iis objects into a JSONArray
    public extractToJSONArray (iisObjectMap, thisResourcePath, thisParentPath, roleName, description){
        JSONArray result = new JSONArray()

        iisObjectMap.each{ name,  propMap ->
            def skipIteration = false
            JSONObject resourceRoleProps = propMapToJson(propMap)

            JSONObject newResourceJson = new JSONObject()
            newResourceJson.put("name", name)
            newResourceJson.put("description", description)
            newResourceJson.put("parent", thisParentPath)
            newResourceJson.put("role", roleName)
            newResourceJson.put("path", "${thisParentPath}/${name}")
            newResourceJson.put("roleProperties", resourceRoleProps)

            //if this resource is an Application,  we need to place it underneath
            //the associated Site on the resource tree
            if (roleName == Globals.APP_ROLE_NAME){
                //alter path to be underneath the associated Site
                newResourceJson.put("path", "${thisResourcePath}/Sites/${name}")

                //name should be the last part of the application path which is the
                //name for all applications
                name = (name =~ /.*\/(.*)/)[0][1]
                if (name.trim().isEmpty() || name == null) {
                    //skip due to name conflicts between sites and applications
                    skipIteration = true
                }
                else {
                    //parent should be the path before the trailing name '(.*)/<name>'
                    thisParentPath = (newResourceJson.get("path") =~ /(.*)\//)[0][1]
                    newResourceJson.put("parent", thisParentPath)
                    newResourceJson.put("name", name)
                }
            }

            if (!skipIteration) {
                result.put(newResourceJson)
            }
        }

        return result
    }

    //add iis objects to the resource tree
    public addResourcesToResourceTree (JSONArray resources){
        for (def i = 0; i < resources.length(); i++){
            //load props from json and create a base resource
            def resourceJsonObject = resources.get(i)
            def resourceName = resourceJsonObject.get("name").trim()
            def resourcePath = resourceJsonObject.get("path")
            def resourceParent = resourceJsonObject.get("parent")
            def resourceDescription = resourceJsonObject.get("description")
            def resourceRole = resourceJsonObject.get("role")
            def resource = resourceHelper.getOrCreateSubResource(resourcePath, resourceParent, resourceName, resourceDescription)

            //now add role properties to the resource we just created
            def resourceRoleProps = jsonToPropMap(resourceJsonObject.get("roleProperties"))
            resourceHelper.addRoleToResource(resource, resourceRole, resourceRoleProps)
        }
    }
}