/*
* Licensed Materials - Property of IBM* and/or HCL**
* UrbanCode Deploy
* UrbanCode Build
* UrbanCode Release
* AnthillPro
* (c) Copyright IBM Corporation 2011, 2017. All Rights Reserved.
* (c) Copyright HCL Technologies Ltd. 2018. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*
* * Trademark of International Business Machines
* ** Trademark of HCL Technologies Limited
*/
import java.nio.charset.Charset

import org.ini4j.Config
import org.ini4j.Wini

import com.urbancode.air.AirPluginTool

AirPluginTool airTool = new AirPluginTool(args[0], args[1])
Properties props = airTool.getStepProperties()

def workDir = new File('.').canonicalFile

def commentChars = ";#"
def fileName = props['file']
def add = props['add']
def remove = props['remove']
def removeSection = props['removeSection']
def addComments = props['addComments']
def poundComments = props['poundComments']
def customEncoding = props['customEncoding']?.trim()

Charset charset = null
if (customEncoding) {
    charset = Charset.forName(customEncoding)
}
else {
    charset = Charset.forName(System.getProperty("file.encoding"))
}

def isComment = { line ->
    // (x as char) as int  <-groovy needs help matching indexOf() signature
    return line && commentChars.indexOf((line.trim()[0] as char) as int) != -1
}

def trimComment = { line ->
    if (line) {
        line = line.trim().substring(1)
    }
    return line
}

def file = new File(fileName)
if (!file.exists()) file.createNewFile()

def ini = new Wini()
Config cfg = ini.getConfig()
cfg.setStrictOperator(true)
cfg.setEmptySection(true)
cfg.setMultiComment(true)
cfg.setFileEncoding(charset)

if (poundComments != null && poundComments.toBoolean() == true) {
    cfg.setCommentChar('#' as char)
}
else {
    cfg.setCommentChar(';' as char)
}
ini.load(file);

try {
    println "Updating file $file"
    def propertyComments = []
    add?.eachLine {
        if (isComment(it)) {
            propertyComments << trimComment(it)
        }
        else if (it && it.trim().length() > 0 && it.indexOf('=') > -1) {
            def index = it.indexOf('=')
            def group
            def name = it.substring(0, index)
            def value = ''
            if (index < it.length() - 1) {
                value = it.substring(index + 1)
            }

            if (name.lastIndexOf('\\') != -1) {
                group = name.substring(0, name.lastIndexOf('\\'))
                name = name.substring(name.lastIndexOf('\\') + 1)
            }
            println "Setting $it"
            if (!group) {
                throw new Exception("Could not detect group name in $it")
            }
            ini.put(group, name, value)
            def groupObject = ini.get(group)
            if (!propertyComments.isEmpty()) {
                propertyComments.each {
                    println "Adding comment to $group\\$name: $it"
                    groupObject.putComment(name, it)
                }
            }
            propertyComments.clear()
        }
    }
    propertyComments = null

    remove?.eachLine {
        if (it && it.trim().length() > 0) {
            println "Removing $it"
            def group
            def name = it
            if (name.lastIndexOf('\\') != -1) {
                group = name.substring(0, name.lastIndexOf('\\'))
                name = name.substring(name.lastIndexOf('\\') + 1)
            }

            if (!group) {
                throw new Exception("Could not detect group name in $it")
            }

            try {
                ini.get(group).remove(name)
            }
            catch (Exception ee) {
                // this is to prevent failing on non-existent values
            }
        }
    }
    addComments?.eachLine {
        def group
        def comment

        if (it && it.trim().length() > 0 && it.indexOf('=') > -1) {
            def indexOfEquals = it.indexOf('=')
            group = it.substring(0, indexOfEquals)
            comment = it.substring(indexOfEquals+1)
        }
        println "Adding Comment $it"
        if (!group) throw new Exception("Could not detect group name in $it")

        ini.putComment(group, comment)
    }
    removeSection?.eachLine {
        def section = it.trim()

        if (section.length() > 0) {
            ini.remove(section)
        }
    }
    ini.store(file)
}
catch (Exception e) {
    def msg = e.message?:e.getClass()
    println "Error updating file $file: ${msg}"
    e.printStackTrace()
    System.exit(1)
}

System.exit(0)
