/**
 * (c) Copyright IBM Corporation 2013, 2017.
 * (c) Copyright HCL Technologies Ltd. 2018, 2019. All Rights Reserved.
 * This is licensed under the following license.
 * The Eclipse Public 1.0 License (http://www.eclipse.org/legal/epl-v10.html)
 * U.S. Government Users Restricted Rights:  Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 */
package com.urbancode.air.plugin.ibmace

import com.urbancode.air.CommandHelper
import com.urbancode.air.ExitCodeException

/**
 * Class to run MQSI script commands
 *
 */
class MQSIHelper {
    final def workDir = new File('.').canonicalFile
    CommandHelper chelper
    def installDir  // installation directory of iib server
    def cmdDir  // directory where mqsi script files exist
    def isWindows

    /**
     * Constructor for MQSIHelper class
     * @param installDir
     * @param isWindows
     */
    public MQSIHelper(def installDir, def isWindows) {
        chelper = new CommandHelper(workDir)
        this.installDir = installDir
        cmdDir = installDir + File.separator + "bin"
        this.isWindows = isWindows

        File commandDir = new File(cmdDir)

        if (!commandDir.isDirectory()) {
            throw new FileNotFoundException("The directory: ${cmdDir} does not exist.")
        }
    }

    /**
     * Create an integration node
     * @param integrationNode
     * @param defaultUser
     * @param defaultPass
     * @param queueManager
     * @param additionalArgs
     */
    void createBroker(def integrationNode, def queueManager, def serviceUser, def servicePass, def additionalArgs) {
        def mqsicreatebroker = createMQCommand("mqsicreatebroker")

        def args = []

        // a queue manager will be created if not specified
        if (queueManager) {
            args << "-q"
            args << queueManager
        }

        // iib 9,11 only required properties
        if (serviceUser) {
            args << "-i"
            args << serviceUser
        }

        if (servicePass) {
            args << "-a"
            args << servicePass
        }

        if (additionalArgs) {
            for (def arg : additionalArgs.split('\n')) {
                if (arg.trim()) {
                    args << arg.trim()
                }
            }
        }

        args << integrationNode

        runMQCommand("Creating integration node: ${integrationNode}...", mqsicreatebroker, args)
    }

    /**
     * Create an Policy
     * @param integrationNode
     * @param PolicyName
     * @param policyType
     * @param propertieskey
     * @param propertiesvalue
     * @param traceFileName
     */

    // >mqsicreateconfigurableservice NewNodeTest 
    // -c Timer -o 'CreatePolicy-1' 
    // -n timeoutIntervalSeconds -v 0 
    // --trace C:\Users\akshayrameshc.parma\IBM\ACET11\workspace\SimplePolicyProject\abc.txt
    // integrationNode, polyName, policyType, propertieskey, propertiesvalue, traceDir)
    void CreatePolicy(def integrationNode, def PolicyName, def policyType, def propertieskey, def propertiesvalue, def traceFileName) {
        def mqsicreatePolicy = createMQCommand("mqsicreateconfigurableservice")

        def args = []

        if (integrationNode) {
            args << integrationNode
        }
        // a policy type
        if (policyType) {
            args << "-c"
            args << policyType
        }
        // a policy Name
        if (PolicyName) {
            args << "-o"
            args << PolicyName
        }
        if (propertieskey) {
            args << "-n"
            args << propertieskey
            args << "-v"
            args << propertiesvalue
        }
        
        if (traceFileName) {
            args << "---trace"
            args << traceFileName
        }

        runMQCommand("Creating Policy: ${integrationNode}...", mqsicreatePolicy, args)
    }

    void UpdatePolicy(def integrationNode, def PolicyName, def policyType, def propertieskey, def propertiesvalue, def traceFileName) {
        def mqsicreateUpdatePolicy = createMQCommand("mqsichangeproperties")

        def args = []

        if (integrationNode) {
            args << integrationNode
        }
        // a policy type
        if (policyType) {
            args << "-c"
            args << policyType
        }
        // a policy Name
        if (PolicyName) {
            args << "-o"
            args << PolicyName
        }
        if (propertieskey) {
            args << "-n"
            args << propertieskey
            args << "-v"
            args << propertiesvalue
        }
        
        if (traceFileName) {
            args << "---trace"
            args << traceFileName
        }

        runMQCommand("Update Policy: ${integrationNode}...", mqsicreateUpdatePolicy, args)
    }
    /**
     * Delete an integration node
     * @param integrationNode
     * @param deleteQueues
     * @param deleteTrace
     */
    void deleteBroker(def integrationNode, boolean deleteQueues, boolean deleteTrace) {
        def mqsideletebroker = createMQCommand("mqsideletebroker")

        def args = []

        if (deleteQueues) {
            args << "-s"
        }

        if (deleteTrace) {
            args << "-w"
        }

        args << integrationNode

        runMQCommand("Delete integration node: ${integrationNode}...", mqsideletebroker, args)
    }

    /**
     * Start an integration node
     * @param integrationNode
     */
    void startBroker(def integrationNode) {
        def mqsistart = createMQCommand("mqsistart")

        def args = [integrationNode]

        runMQCommand("Starting integration node: ${integrationNode}...", mqsistart, args)
    }

    /**
     * Stop an integration node
     * @param integrationNode
     */
    void stopBroker(def integrationNode) {
        def mqsistop = createMQCommand("mqsistop")

        def args = [integrationNode]
        //TODO
        //'-i' forces the integration node to stop immediately (use with caution).


        runMQCommand("Stopping integration node: ${integrationNode}...", mqsistop, args)
    }

	/**
	 * Deploy bar file
	 * @param integrationNodeName
	 * @param integrationNodeFileName
	 * @param ipAddress
	 * @param port
	 * @param BARFile
	 * @param deployedObjects
	 * @param integrationServerName
	 * @param clear
	 * @param traceFileName 
	 * @param timeoutValue
	 */
	void deployBarFile(def integrationNodeName, def integrationNodeFileName, def ipAddress, def port, def BARFile, def deployedObjects, def integrationServerName, def clear, def traceFileName, def timeoutValue, def userId, def password) {
		def mqsideploy = createMQCommand("mqsideploy")

		def args = []

        def authUrl = 'tcp://' + userId + ':' + password + '@' + ipAddress
		
		if (integrationNodeName) {
			args << integrationNodeName
		}
		
		if (integrationNodeFileName) {
			args << "-n"
			args << integrationNodeFileName
		}
		
		if (ipAddress) {
			args << "-i"
			args << authUrl
		}
		
		if (port) {
			args << "-p"
			args << port
		}
		
		if (BARFile) {
			args << "-a"
			args << BARFile
		}
		
		if (deployedObjects) {
			args << "-m"
			args << deployedObjects
		}
		
		if (integrationServerName) {
			args << "-e"
			args << integrationServerName
		}
		
		if (clear) {
			args << "-m"
			//args << clear
		}
		
		if (traceFileName) {
			args << "-v"
			args << traceFileName
		}
		
		if (timeoutValue) {
			args << "-w"
			args << timeoutValue
		}		

		runMQCommand("Deploy Bar File: ${BARFile}...", mqsideploy, args)
	}


    /**
     * Acquire the specified mqsi script file in the command directory if it exists
     * @param scriptFile
     * @return String path to script file
     */
    private def createMQCommand(def scriptFile) {
        createMQCommand(scriptFile, "")
    }

    /**
     * Acquire the specified mqsi script file with the specified extension
     * @param scriptFile
     * @param extension
     * @return String path to script file
     */
    private def createMQCommand(def scriptFile, def extension) {
        if (isWindows) {
            if (!extension) {
                extension = ".exe"
            }

            scriptFile = scriptFile + extension
        }

        File mqFile = new File(cmdDir, scriptFile)

        if (!mqFile.isFile()) {
            throw new FileNotFoundException("Cannot find file ${mqFile.absolutePath}")
        }

        return mqFile.toString()
    }

    /**
     * Run a CommandHelper command
     * @param msg
     * @param command
     * @param args
     */
    private void runMQCommand(def msg, def command, def args) {
        def cmdArgs = []
        def mqsiprofile = createMQCommand("mqsiprofile", ".cmd")

        if (!isWindows) {
            def argString = ""
            for (def arg : args) {
                argString += " ${arg}"
            }

            cmdArgs = ["/bin/bash", "-c", "source ${mqsiprofile}; ${command}${argString}"]
        }
        else {
            cmdArgs = [mqsiprofile, "&", command]

            for (def arg : args) {
                cmdArgs << arg
            }
        }

        chelper.runCommand(msg, cmdArgs)
    }
}
