#!groovy
@Grab('org.yaml:snakeyaml:1.17')
import jenkins.model.Jenkins;
import jenkins.model.GlobalConfiguration
import net.sf.json.JSONArray;
import net.sf.json.JSONObject
import org.yaml.snakeyaml.Yaml
import io.jenkins.plugins.casc.ConfigurationAsCode
import jenkins.security.UpdateSiteWarningsConfiguration

Yaml parser = new Yaml()

def casc = ConfigurationAsCode.get()
def configPath = casc.getStandardConfig()[0]
def symlFiles = new FileNameFinder().getFileNames(configPath, '**/*.syml', '.**/ **/.*')
def configs = []
symlFiles.each {
    configs = configs + parser.load((it as File).text)
}

class Globals {
    public static Boolean compareObjects( Object a, b) {
        return Jenkins.XSTREAM.toXML(a) == Jenkins.XSTREAM.toXML(b)
    }
}

class UpdateSiteWarnings {
    UpdateSiteWarnings() {}
    Boolean changed = false
    def instance = Jenkins.instance
    void configure(params) {
        def config = GlobalConfiguration.all().get(UpdateSiteWarningsConfiguration.class)
        def _config = new UpdateSiteWarningsConfiguration()

        _config.configure(null, JSONObject.fromObject(params))
        if (! Globals.compareObjects(config, _config)) {
            config.configure(null, JSONObject.fromObject(params))
            changed = true
        }
        _config = null
    }
}

class CSP {
    CSP() {}
    Boolean changed = false
    def instance = Jenkins.instance
    void configure(param) {
        String currentPolicy = System.getProperty("hudson.model.DirectoryBrowserSupport.CSP")
        String newPolicy = param.policy.trim()
        if ( currentPolicy != newPolicy ){
            System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", newPolicy)
            changed = true
        }
    }
}

class GerritTrigger {
    GerritTrigger() {}

    def instance = Jenkins.instance
    Boolean changed = false
    def defaultServerParam = [
        noConnectionOnStartup: false,
        gerritBuildStartedVerifiedValue: 0,
        gerritBuildSuccessfulVerifiedValue: 1,
        gerritBuildFailedVerifiedValue: -1,
        gerritBuildUnstableVerifiedValue: 0,
        gerritBuildNotBuiltVerifiedValue: 0,
        gerritBuildStartedCodeReviewValue: 0,
        gerritBuildSuccessfulCodeReviewValue: 0,
        gerritBuildFailedCodeReviewValue: 0,
        gerritBuildUnstableCodeReviewValue: -1,
        gerritBuildNotBuiltCodeReviewValue: 0,
        gerritVerifiedCmdBuildStarted:
            "gerrit review <CHANGE>,<PATCHSET> --message 'Build Started <BUILDURL> <STARTED_STATS>' --verified <VERIFIED> --code-review <CODE_REVIEW>",
        gerritVerifiedCmdBuildSuccessful:
            "gerrit review <CHANGE>,<PATCHSET> --message 'Build Successful <BUILDS_STATS>' --verified <VERIFIED> --code-review <CODE_REVIEW>",
        gerritVerifiedCmdBuildFailed:
            "gerrit review <CHANGE>,<PATCHSET> --message 'Build Failed <BUILDS_STATS>' --verified <VERIFIED> --code-review <CODE_REVIEW>",
        gerritVerifiedCmdBuildUnstable:
            "gerrit review <CHANGE>,<PATCHSET> --message 'Build Unstable <BUILDS_STATS>' --verified <VERIFIED> --code-review <CODE_REVIEW>",
        gerritVerifiedCmdBuildNotBuilt:
            "gerrit review <CHANGE>,<PATCHSET> --message 'No Builds Executed <BUILDS_STATS>' --verified <VERIFIED> --code-review <CODE_REVIEW>",
        verdictCategories: [
            [ verdictValue: 'Code-Review', verdictDescription: 'Code Review' ],
            [ verdictValue: 'Verified', verdictDescription: 'Verified' ],
        ]
    ]

    Boolean compareObjects( Object a, b) {
        String aXML = Jenkins.XSTREAM.toXML(a).replaceAll(/\{AQA[^\}]+\}/) {
                          hudson.util.Secret.decrypt(it) }
        String bXML = Jenkins.XSTREAM.toXML(b).replaceAll(/\{AQA[^\}]+\}/) {
                          hudson.util.Secret.decrypt(it) }
        return aXML == bXML
    }

    void configure(params) {
        if ( Jenkins.instance.pluginManager.activePlugins.find { it.shortName == "gerrit-trigger" } == null ) {
            return
        }
        def gerritPlugin = Jenkins.instance.getPlugin(com.sonyericsson.hudson.plugins.gerrit.trigger.PluginImpl.class);

        // Configure common parameters
        def pluginConfig = gerritPlugin.getPluginConfig()
        def _pluginConfig = new com.sonyericsson.hudson.plugins.gerrit.trigger.config.PluginConfig()

        _pluginConfig.setValues(JSONArray.fromObject(params))
        if (! compareObjects(pluginConfig, _pluginConfig)) {
            pluginConfig.setValues(JSONArray.fromObject(params))
            changed = true
        }
        _pluginConfig = null

        // Configure servers
        params.servers.each { _name, _params ->
            def __params = defaultServerParam + _params
            def values = JSONArray.fromObject(__params)
            def server = gerritPlugin.getServer(_name)

            if (! server) {
                server = new com.sonyericsson.hudson.plugins.gerrit.trigger.GerritServer(
                    _name, __params.noConnectionOnStartup)
            }
            def config = server.getConfig()
            def _server = new com.sonyericsson.hudson.plugins.gerrit.trigger.GerritServer(
                _name, __params.noConnectionOnStartup)
            def _config = _server.getConfig()
            _config.setValues(values)
            _server.setConfig(_config)
            if (! compareObjects(server, _server)) {
                changed = true
                if ( gerritPlugin.containsServer(_name) ) {
                    gerritPlugin.removeServer(gerritPlugin.getServer(_name))
                }
                gerritPlugin.addServer(_server)
                _server.start()
                if (! __params.noConnectionOnStartup) {
                    _server.startConnection()
                }
            }
        }
    }
}

configs.each { params ->
    params.each { _name, _params ->
        def clazz = Class.forName(_name)
        if (clazz) {
            def act = clazz.newInstance()
            act.configure(_params)
            if (act.changed) {
                act.instance.save()
            }
        }
    }
}
