/*
 * 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.
 */

import com.urbancode.air.AirPluginTool
import com.urbancode.air.CommandHelper
import com.urbancode.air.plugin.iisconfiguration.helper.XMLToCompareJSONHelper
import com.urbancode.air.plugin.iisconfiguration.helper.MSDeployCmdLineHelper
import com.urbancode.air.plugin.iisconfiguration.helper.FileUtilReplaceTokens
import org.codehaus.jettison.json.JSONObject
import org.codehaus.jettison.json.JSONArray
import groovy.util.AntBuilder
import com.urbancode.air.plugin.iisconfiguration.Globals
import com.urbancode.air.plugin.iisconfiguration.Util
import groovy.io.FileType

//initialize plugin tools
def s = File.separator
def apTool = new AirPluginTool(args[0], args[1])
def isWindows = apTool.isWindows
def props = apTool.getStepProperties()
def logDir = new File(props["PLUGIN_INPUT_PROPS"]).getParentFile()
def commandHelper = new CommandHelper(new File(".").canonicalFile)
def antBuilder = new AntBuilder()
def fileUtilReplaceTokens = new FileUtilReplaceTokens()

//initialize IIS variables
def msDeployHelper = new MSDeployCmdLineHelper()
def webDeployPath = props['webDeployPath']
def argString = props['argString']?.trim()
def verb = "sync"
def srcType = ""
def srcPath = ""
def destType = "package"
def destPath = new File("iisConfiguration.zip").getCanonicalPath()

def main = {
    //retrieve properties from this component version configuration
    def metaData = new Properties()
    def metaDataFile = Util.findFileRecursivelyByName(Globals.UCD_METADATA_FILE_NAME)
    metaData.load(metaDataFile.newDataInputStream())
    def configFolderStr = metaData.getProperty(Globals.PROPERTY_CONFIG_FOLDER)
    def resourceRoleName = metaData.getProperty(Globals.PROPERTY_RESOURCE_ROLE)
    def thisResourceParentPath = (props['resourcePath'] =~ /(\/.*)\/.*/)[0][1]

    //<<1>> Read archive.xml from current version
    def versionArchiveXML = new File("${configFolderStr}/${Globals.CONFIG_FILE}")
    def isIgnoreErrors = true

    //retrieve srcType and srcPath for live configuration discovery
    def srcTypeAndPath = Util.formatPathAndTypeFromResourceRoleName(resourceRoleName, thisResourceParentPath)
    srcPath = srcTypeAndPath['path']
    srcType = srcTypeAndPath['type']

    //<<2>> Use the msdeployTarget in archive.xml to run a second discovery on the same target and retrieve the archive.xml from live environment
    //run msdeploy to perform package sync
    println("WARNING: Performing live compare on an IIS app, site, app pool, or webserver that does not exist yet will result in errors printing to the output log. This is expected and will appear in the live compare window as empty for discovered resources.")
    def liveDiscoveryExitVal = msDeployHelper.runMSDeployScript(webDeployPath, verb, srcType, destType, srcPath, "\"${destPath}\"", "", isIgnoreErrors)

    //create empty JSON and file for live discovery. if the discovery above was unsuccessful, we should assume the user created a brand new
    //resource role on UCD and it does not exist on IIS yet. (i.e. the user has not performed an apply and wants to see changes that will happen)
    //we should still show that there is a lack of that resource role on the compare and avoid throwing exceptions
    JSONArray liveConfigJSON = new JSONArray()
    def liveConfigJSONFile = new File("${logDir.getCanonicalPath()}/comparison.json.compare")
    if(liveDiscoveryExitVal == "0"){
        //if we are here, then the live discovery successfully found a target, we can continue as normal
        //unzip the config we just created so we can retrieve the live config data from it
        def liveConfigurationFolder = new File("liveConfiguration")
        antBuilder.unzip(   dest:liveConfigurationFolder.getCanonicalPath(),
                            src:destPath,
                            overwrite:"true" )

        //cleanup zip
        new File(destPath).delete()
        def liveArchiveXML = new File("${liveConfigurationFolder}/${Globals.CONFIG_FILE}")

        //<<3>> Replace tokens
        fileUtilReplaceTokens.run(props, versionArchiveXML.getParentFile().getName())

        //live config to compare to
        liveConfigJSON = XMLToCompareJSONHelper.getCompareJSONFromXMLFile(liveArchiveXML)
    }
    //write to compare file then free up memory
    liveConfigJSONFile.text = liveConfigJSON.toString(4)
    liveConfigJSON = null

    //<<4>> Convert both archive.xml into JSON format for easy config drift compare
    //local config
    JSONArray localConfigJSON = XMLToCompareJSONHelper.getCompareJSONFromXMLFile(versionArchiveXML)
    def localConfigJSONFile = new File("${logDir.getCanonicalPath()}/comparison.json")
    //write to compare file then free up memory
    localConfigJSONFile.text = localConfigJSON.toString(4)
    localConfigJSON = null

    //now that the 2 files are in the log directory with ".compare" on one, UCD will compare the 2 files
}

//go
main()