import java.util.concurrent.Callable
import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicBoolean
import java.awt.AWTException
import java.awt.Font
import java.awt.Image
import java.awt.Menu
import java.awt.MenuItem
import java.awt.PopupMenu
import java.awt.SystemTray
import java.awt.TrayIcon
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import javax.swing.JOptionPane
import javax.imageio.ImageIO

import static Services.*
import static ServiceControl.*
/*
* open CMD  -> gradle health
*
* */

group 'org.onap.sdc'
version '1.01-SNAPSHOT'

apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: "org.hidetake.ssh"
apply plugin: 'java-gradle-plugin'
apply plugin: 'idea'

sourceCompatibility = 1.8

buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'org.codehaus.groovy:groovy-all:2.4.12'
        classpath "org.hidetake:gradle-ssh-plugin:2.9.0"
    }
}

enum Services {
    BACKEND ,   //be
    FRONTEND ,  //fe
    DB ,        //cassandra
    CACHING ,   //elawsrticsearch
    SECURITY ,   //webseal
    ALL //all services
}
enum ServiceControl {
    HEALTH ,
    START ,
    RESTART ,
    STOP ,
    KILL
}
enum Environment {
    OLD_VAGRANT , PROD_VAGRANT , ONAP_VAGRANT
}
//env variables
//fill YOUR_WINDOWS_USER_HOME
project.ext.set("VM_TYPE", Environment.ONAP_VAGRANT) //flags to use new vagrant configuration
//project.ext.set("NEW_VAG",Boolean.FALSE) //flags to use new vagrant configuration
project.ext.set("IS_HOTSWAP",Boolean.FALSE) //flags to use new vagrant configuration
project.ext.set("PROJECT_PATH", System.getenv("SDC")) //ex. 'C:\\GIT_WORK\\asdc\\sdc')
project.ext.set("VAGRANT_HOME", isProductionVM() ? System.getenv("NEW_VAG") : isOnapVM() ? System.getenv("ONAP_VAG") :System.getenv("VAG")) //ex. 'C:\\GIT_WORK\\vagrant-asdc-all-in-one')
project.ext.set("USER_HOME", "${System.getenv("USERPROFILE")}\\.ssh")
project.ext.set("BE_REMOTE", isProductionVM() ? '/opt/app/jetty/base/be' : '/home/vagrant/catalog-be' )
project.ext.set("FE_REMOTE", isProductionVM() ? '/opt/app/jetty/base/fe' : '/home/vagrant/catalog-fe' )
project.ext.set("VAGRANT_USER",     isProductionVM() ? 'm11981' : 'vagrant' )
project.ext.set("RSA_PRIVATE_KEY_PATH", isProductionVM() ? "$VAGRANT_HOME/id_rsa" : '' )
project.ext.set("VAGRANT_PASSWORD", isProductionVM() ? 'Aa123456' : 'vagrant' )
project.ext.set("X_FOLDER",'/xFolder' )
project.ext.set("BE_DEPENDENCIES", 'common-be,common-app-api,catalog-dao,catalog-model,security-utils' )
project.ext.set("command", [ (ALL) :  [  (HEALTH) : { isProductionVM() ? 'sudo curl -i http://localhost:8181/sdc1/rest/healthCheck' : isOnapVM() ? 'sudo -i /data/scripts/docker_health.sh' : 'curl -i localhost:8080/sdc2/rest/healthCheck' } ,
                                         (KILL) : { isProductionVM() ? 'sudo pkill java' : isOnapVM() ? 'sudo -i docker kill $(docker ps -q)' : 'pkill java'} ]  ,   //  TODO: refine kill only for services
                             (BACKEND) : [  (START) : { isProductionVM() ? 'sudo service jettyBE start' : isOnapVM() ? 'sudo -i docker start sdc-BE' : 'service catalog-be start'} ,
                                            (STOP) : { isProductionVM() ? 'sudo service jettyBE stop' : isOnapVM() ? 'sudo -i docker stop sdc-BE' : 'service catalog-be stop'} ,
                                            (RESTART) : { isProductionVM() ? 'sudo service jettyBE restart' : isOnapVM() ? 'sudo -i docker restart sdc-BE' : 'service catalog-be restart'}]  ,
                             (DB) : [  (START) : { isProductionVM() ? 'sudo service cassandra start' :  isOnapVM() ? 'sudo -i docker start sdc-cs' : 'start-asdc-storage.sh' } ,
                                       (STOP) : { isProductionVM() ? 'sudo service cassandra stop' : isOnapVM() ? 'sudo -i docker stop sdc-cs' : 'service cassandra stop'} ,
                                       (RESTART) : { isProductionVM() ? 'sudo service cassandra restart' : isOnapVM() ? 'sudo -i docker restart sdc-cs' : 'service cassandra restart'} ]  ,
                             (FRONTEND): [  (START) : {  isProductionVM() ? 'sudo service jettyFE start' : isOnapVM() ? 'sudo -i docker start sdc-FE' : 'service catalog-fe start'   } ,
                                            (STOP) : { isProductionVM() ? 'sudo service jettyFE stop' : isOnapVM() ? 'sudo -i docker stop sdc-FE' : 'service catalog-fe stop'} ,
                                            (RESTART) : {  isProductionVM() ? 'sudo service jettyFE restart' : isOnapVM() ? 'sudo -i docker restart sdc-FE' : 'service catalog-fe restart'   } ]  ,
                             (CACHING): [  (START) : { isProductionVM() ? 'sudo service elasticsearch start' : isOnapVM() ? 'sudo -i docker start sdc-es' : 'echo "starting es is not yet supported"'   } ],
                             (SECURITY): [  (START) : {  isProductionVM() ? 'sudo docker start sdc-WebSeal-Simulator' : isOnapVM() ? 'sudo -i /data/scripts/simulator_docker_run.sh -r $(echo $(sudo -i docker images onap/sdc-simulator | grep onap/sdc-simulator | head -1 |  awk \'{print $2}\'))' :  'service webseal-simulator start'   } ,
                                            (STOP) : { isProductionVM() ? 'sudo docker stop sdc-WebSeal-Simulator' : isOnapVM() ? 'sudo -i docker stop sdc-sim' : 'service webseal-simulator stop'} ,
                                            (RESTART) : { isProductionVM() ? 'sudo docker restart sdc-WebSeal-Simulator' : isOnapVM() ? 'sudo -i docker restart sdc-sim' : 'service webseal-simulator restart'}]
                             ] )      //abstraction level to shell scripts , support old and new vagrant bash commands

//icons
project.ext.set("warnImg",'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADvSURBVDhPY2RgYPgPxGQDiAGLXkB4UMD56DuD9YFUhj179oD5Li4uDEcdZjN8l+ME8+EgTgLTAJDm7zWKYPb/enUwzdh4E0xzttxHNQRoABOUCQYYmj+9QrCBACQHUoMM4AYga74ZDiRAmvnEwHwQGywGBOiGgA1A16wmJYjQDAJANkgMmyEosYBVMzIAuuTWs/cM6iuhfCCAGwDWrAHxKyFw68ZNuCE40wGygcga0AEkEEHRiIxxASzqUKKRHIAwAJgo4BgXwKIGxQUgf8MwOsAlh+EFUMDBMAxgE0MGoLwAignSMFQPzmgkDjAwAACSmn13nChk1QAAAABJRU5ErkJggg==')
project.ext.set("okImg1",'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAD4SURBVDhPY2RgYPgPxGQDiAGLXkB4UMD56DuD9YFUhj179oD5Li4uDEcdZjN8l+ME8+EgTgLTAJDm7zWKYLbSRh8wfc9/C5jmbLmPagjQACYoEwwwNLMxgzHMIJAcSA0ygBuArFm81gyi+ddfCAaywWJAgG4I2AB0zdxWkhCNMABkg8SwGYISC1g1IwOgS74ee87wsvkUVADJAJjpyIDbRAxMfz3zCkwjA5ghONMB2DVIBiDbigwggQiKRmSMC2BRhxKN5ACEAcBEAce4ABY1LFAaDLAFJAwgyyGHB4YXQAEHwzCATQwZgPICKCZIw1A9OKOROMDAAAA4gXvZorg7ZgAAAABJRU5ErkJggg==')
project.ext.set("okImg2" , 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADjSURBVDhPY2RgYPgPxGQDiAGLXkB4UMD56DuD9YFUhj179oD5Li4uDEcdZjN8l+ME8+EgTgLTAJDm7zWKYPbWZ7Jg2lvqMZjmbLmPagjQACYoEwywaQYBGBskB1KDDOAGIGuetFsUTCMDmBi6IWAD0DUra3OA2cgAJIbNEJRYwKUZGdy9+oMhz/U1lIdkADZnwwwDaUIHMENwpgNk16DbigwggQiKRmSMC2BRhxKN5ACEAcBEAce4ABY1LFAaDLAFJAwgyyGHB4YXQAEHwzCATQwZgPICKCZIw1A9OKOROMDAAAAZD3X55epfOAAAAABJRU5ErkJggg==')
project.ext.set("errorImg" , 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADlSURBVDhPY2RgYPgPxGQDiAGLXkB4UMD56DuD9YFUhj179oD5Li4uDEcdZjN8l+ME8+EgTgLTAJDm7zWKYPZbGRUwLfzkDpjmbLmPagjQACYoEwywaQYBGBskB1KDDOAGIGtexisCppEBTAzdELAB6Jrd+QXAbGQAEsNmCEos4NKMDHZ+/MAQ9fkNlIdkADZnwwwDaUIHyIaADMDAQAP/AwMPjEFsbGpAGGs6AEUPsnfgzsaiDiUayQUgF2A4jaAXoHpQXAByNgyjA1xyGF4A+RuGYQCbGDLA6gWCGKoHJSGRDhgYAL/hkunRq+joAAAAAElFTkSuQmCC')
project.ext.set("unavailableImg" , 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAABJ0AAASdAHeZh94AAAAB3RJTUUH4QwNDgEDrNoaqgAAAOhJREFUOMulkz8OgjAUhz8MQ7mBkwnnkBAH4mbCCdxcXLwAoxdwYXHjBCRupoMheg4TJ29QNhwshMofSfpLOry2v6/vta8OUGEhF4DsbUx6L8XytkNKCUAURTxWZ9TCM93buQb8mFXiI4E43gCQ5xeQPt7x2YG4fWa0OQwDhBANRCVdyGyKOQyDJhuV+HgvZQLGzABCiEGI036FPnNbZVlSFPfvnWg1gJpea72OjPh6lUZcQ5yhPkjTkxHv94fpfcB23t81PftmWMr9e+pQZjobd6zuobX2fViXAFCRvSv9GtOH9ji23/kDswRrCVqtQOAAAAAASUVORK5CYII=')


//health params
project.ext.set("trayIcon", null)
project.ext.set("lastStatus", null)
project.ext.set("isStopHealthCheck", false)
project.ext.set("isHaltHealth", new AtomicBoolean(false) )
project.ext.set("startedAwait", Long.MAX_VALUE)
project.ext.set("logFile", 'C:/ProgramData/all.log')
project.ext.set("pomList" , ["${System?.getenv('SDC')}/catalog-fe/pom.xml" ,"${System?.getenv('SDC')}/catalog-be/pom.xml" ] )   //empty list will scan all openecomp poms
project.ext.set("pomChangesMap" , [:] )
project.ext.set("beConfigFilesToCopyMapping" , [ 'src/main/resources/config/*.yaml' : 'config/catalog-be/' ,
                                               'src/main/resources/config/*.properties' : 'config/catalog-be/'] )

//menu item strings
project.ext.set("toggleHealthString" , "Halt Health" )
//menu item
project.ext.set("toggleHealthItemView" , null )

//other
project.ext.set("IS_MVN_INSTALL",false)
project.ext.set("executor" , null )
project.ext.set("lockObj" , new Object() )

def hash( List list ){
    def map = list?.collectEntries { File file -> [(file?.absolutePath) : file?.text?.hashCode() ]}

    map
}

def pomChanges(){
    long started = System.currentTimeMillis()
    if ( !pomList )
        listPom()
    //find hash changes
    def changes = pomList?.findAll {
        def File file = new File(it);
        pomChangesMap[it] != file?.text?.hashCode()
    }
    println "\n\n[MasterD][POM]--> detected changes for -> $changes"
    //update changes in map
    changes?.each { pomChangesMap[it] = new File(it)?.text?.hashCode() }
    println "\n\n[MasterD][POM]--> pom map -> $pomChangesMap"

    println """
            ****** POM changes detection finished after -> ${System.currentTimeMillis()- started}ms  ******
            """

    changes
}
//list pom with updated file hashes
def listPom(){
    long started = System.currentTimeMillis()
    if (!pomList) {
        def tree = fileTree( PROJECT_PATH ).include '**/pom.xml'//.filter { it.isFile() && it?.toString()?.toLowerCase()?.endsWith('pom.xml') }
        //println "$PROJECT_PATH list is ->${ list?.collect { it?.absolutePath } }"
        //flatten and filter openecomp poms
        pomList = tree?.flatten()?.findAll { File file -> file?.text?.contains('org.openecomp.sdc') }?.collect {File file -> file?.absolutePath }
    }
    pomChangesMap = pomList.collectEntries { absolutePath ->[ ( absolutePath ) : new File(absolutePath)?.text?.hashCode() ] }

    println """ [MasterD][Init] intializing POM detector

            *********       POM listing finished after -> ${System.currentTimeMillis()- started}ms    *********
            """
    return pomList
}


task initialization(){
    listPom()
    executor = Executors.newCachedThreadPool();
}

def parallel( closure ){
    executor?.submit(new Callable<Object>(){
        @Override
        public Object call() {
            closure();
            return null;
        }
    })
}
/*class Preferences {
    def String Username
    def String IsNewVagrant
    def String IsRapidMode
}

def initXFolder(){
    def folder = new File(X_FOLDER);
    folder?.exists() ?: folder?.mkdirs()

    new File("${folder?.absolutePath}/$PREFERENCES_FILENAME")
}*/

task tester{
    /*doLast{
        //postStat(10000, "shay" , "report/index")
        listPom()
        new File('catalog-be\\pom.xml') << "#hello"
        pomChanges()
    }*/
}


def fetchFilesByExtention(remote, local , ext ){
    ssh.run {
        def started = System.currentTimeMillis()
        println "folder diff"
        session(remotes.vagrant) {
            //execute "cd /home/vagrant/catalog-be/tmp ; ls -lt | grep catalog-be" //todo- use my dates to filter
            get from: remote  , into: local , filter: {  it?.absolutePath =~ /jetty.*catalog-be.*\.dir.*\.$ext/  } // {  it?.absolutePath =~ /.*catalog-be.*dir.*classes.*/  }
        }
        println "fetched files in ${System.currentTimeMillis() - started} ms"
    }
}

def updateRemoteFile(String remote , String local){
    ssh.run {
        def to = "$BE_REMOTE${remote[remote?.indexOf("tmp\\")..remote.size()-1].replaceAll("\\\\","/")}"
        println "copying $local \nto\n $to"
        session(remotes.vagrant) {
            put from: local  , into: to }
    }
}

def compareAndSwap(){
    def final LIMIT = 10
    def newClasses = new File("$PROJECT_PATH\\catalog-be\\target\\classes")
    def File jettyClasses ;
    //locate classes
    println "traversing.."
    new File("build/hotswap").traverse { if (it?.directory && it?.name?.equals("classes")){
        jettyClasses = it
        return;
    }  }
    def jettyClassesList = []
    jettyClasses?.traverse { jettyClassesList << it }

    println "$jettyClasses"
    //Sort compiled classes
    def files = []
    newClasses?.traverse {  files << it }
    def result = files.sort{ a,b -> b.lastModified() <=> a.lastModified() }
    println "show only last $LIMIT changes"
    result[0..LIMIT]?.each{ println it?.lastModified() +" | "+ it?.name + (it?.directory ? "[Directory]" : "") } //show only last 10 changes

    //update
    def changesMap = [ : ] //<old,new>
    println "updating changes"
    result[0..LIMIT]?.each { File f -> def File other = jettyClassesList.find{ File other-> other?.absolutePath?.endsWith(f?.name) };
        if ( !(f.directory) && f?.text?.hashCode() != other?.text?.hashCode() )
            updateRemoteFile( other?.getAbsolutePath() , f?.getAbsolutePath() )
    } //use hashing
}

task hotswap(){
    doLast {
        new File("build/hotswap")?.deleteDir()
        new File("build/hotswap")?.mkdirs()
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        fetchFilesByExtention( "$BE_REMOTE/tmp/" , 'build/hotswap' , "class")
        compareAndSwap()
    }
}

remotes {
    vagrant {
        host = '127.0.0.1'
        port = 2222
        user = VAGRANT_USER
        password = VAGRANT_PASSWORD
        identity = isProductionVM() ? new File(RSA_PRIVATE_KEY_PATH) : null
    }

}

def isProductionVM(){
  return VM_TYPE?.equals(Environment.PROD_VAGRANT)
}

def isOnapVM(){
    return VM_TYPE?.equals(Environment.ONAP_VAGRANT)
}

def gitLatest(){

}

def newEcoSystem(){
    //cleanTitan()
    backupDB() //and clean all
    //restoreDB() //restore latest
    createSchema()
    fillSchema()
    postCreate()
    startAll()
    //todo- conside updating from git
    updaterBEFull()
    updaterFE()
}
def importHeatTypes(){
   //todo- impl
}
def postCreate(){
    importNormative()
    importHeatTypes()
}
def fillSchema(){
    // add conformence level
}
def createSchemaPreStep(){
    //todo- DB up
}
def createSchemaPostStep(){
    ////todo- impl create amdocs dox
}
def createSchema(){
    createSchemaPreStep()
    //todo- create schema
    //todo- create titan
    createSchemaPostStep()
}

def cleanTitan(){
    execSafe{
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                execute "sudo cqlsh -e 'DROP KEYSPACE titan;'"
                println "[MasterD][DB_DROP]-> Dropped 'titan' KEYSPACE."
            }
        }
    }
}
task cleanTitan {
    doLast{
        cleanTitan()
    }
}

task fetchE2EDB(){
    doLast{
        fetchE2EDB()
    }
}
def fetchE2EDB(){
    execSafe{
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                def tmp = '$CASSANDRA_HOME/backup/e2e'
                //execute 'mkdir $CASSANDRA_HOME/backup/e2e/'
                //execute 'wget http://135.76.210.202:8080/ETE_backup_files/latest_ETE_backup_file.zip -P /vagrant/db'
                println "[MasterD] download finished, unzipping.."
                execute "unzip -u $tmp/latest_ETE_backup_file.zip" //execute 'unzip -u /vagrant/db/latest_ETE_backup_file.zip'//'
                def folder = execute "cd $tmp; ls -d -- */"
                println "[MasterD] unzipping finished into -> $folder , untaring.."
                execute "tar zxf $tmp/$folder/* --strip 3 -C" +'$CASSANDRA_HOME/data | pv -l >/dev/null'
                println "[MasterD][E2E_DB]-> Downloaded & unzipped e2e data successfully."
            }
        }
    }
}
def copyExplodedBE() {
    execSafe{
        println "[MasterD][BackEnd] copying exploded war."
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        long started = System.currentTimeMillis()
        def dirPath = "${PROJECT_PATH}/catalog-be/target/catalog-be-1.1.0-SNAPSHOT"
        def dir = new File(dirPath);
        println "[MasterD][BackEnd] copying ${dir?.directorySize()/(1024*1024)} MB, from ${dir?.name} to $BE_REMOTE/webapps"
                ssh.run {
                    session(remotes.vagrant) {
                        execute "rm -R $BE_REMOTE/webapps/catalog-be-1.1.0-SNAPSHOT"
                        put from: dir?.absolutePath , into: "$BE_REMOTE/webapps"
                    }
                }
        println "[MasterD][BackEnd] Successfully copied exploded war in ${System.currentTimeMillis()-started}ms."
    }
}
task copyExplodedBE(){
    doLast{
        copyExplodedBE()
    }
}
def backupDB() {
    execSafe{
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                execute 'mkdir -p $CASSANDRA_HOME/backup'
                def res = execute 'mv $CASSANDRA_HOME/data $CASSANDRA_HOME/backup/data_$(date +\'%Y_%m_%d__%H:%M:%S\')'
                println "[MasterD][DB_BACKUP]-> snapshot DB finished. $res"
            }
        }
    }
}
task backupDB{
    doLast{
        backupDB()
    }
}

def restoreDB(){
    execSafe{
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                println "[MasterD]-> restoring DB"
                execute 'mkdir -p $CASSANDRA_HOME/data'
                def res = execute 'mv $CASSANDRA_HOME/backup/data_*/* $CASSANDRA_HOME/data'
                println "[MasterD]-> DB restore FINISHED!! $res"
            }
        }
    }
}
task restoreDB() {
    doLast {
        restoreDB()
    }
}

def vm( ){
    exec{
        if (VAGRANT_HOME){
            workingDir VAGRANT_HOME	//vagrant path
            println "*****************\nworking dir -> $VAGRANT_HOME"
            commandLine "cmd","/c", "vagrant up"
            //args = [ ]
        } else {
            println "[MasterD]--> please define windows enviroment variable VAG pointing to vagrant project"
        }
    }
}

task vm{
    doLast{
        vm()
    }
}

def copyFE() {
    println "[MasterD][FrontEnd] starting war copy."
    ssh.settings {
        knownHosts = allowAnyHosts
    }
    long started = System.currentTimeMillis()
    def target = "${PROJECT_PATH}/catalog-fe/target/"
    def files = GFileUtils.listFiles( new File(target) , ["war"] as String[] , false);
    files?.each{ File file ->
        if (!file?.name?.contains('classes')){
            println "[MasterD][FrontEnd] copying ${file.length()/(1024*1024)} MB, from ${file?.name} to $FE_REMOTE/webapps"
            ssh.run {
                session(remotes.vagrant) {
                    if ( isProductionVM() )
                        execute 'sudo chmod -R 777 /opt/app/jetty/base/fe/webapps'
                    put from: file?.absolutePath , into: "$FE_REMOTE/webapps"
                }
            }
        }

    }
    println "[MasterD][FrontEnd] Successfully copied war in ${System.currentTimeMillis()-started}ms."
}

task deployFE{
    doLast {
        copyFE()
    }
}


def copyBE(){
    println "[MasterD][BackEnd] starting war copy."
    ssh.settings {
        knownHosts = allowAnyHosts
    }
    def target = "${PROJECT_PATH}/catalog-be/target/"
    def files = GFileUtils.listFiles( new File(target) , ["war"] as String[] , false);
    long started = System.currentTimeMillis()
    files?.each{ File file ->
        if (!file?.name?.contains('classes')){
            println "[MasterD][BackEnd] copying ${file.length()/(1024*1024)} MB, from ${file?.name} to $BE_REMOTE/webapps"
            ssh.run {
                session(remotes.vagrant) {
                    if (isProductionVM())
                        execute 'sudo chmod -R 777 /opt/app/jetty/base/be/webapps'
                    put from: file?.absolutePath , into: "$BE_REMOTE/webapps"
                }
            }
        }
    }
    println "[MasterD][BackEnd] SUCCESSFULY copied be war in ${System.currentTimeMillis()-started}ms."
}

task deployBE {
    doLast {
        copyBE()
    }
}
def compileFE(){
    exec{
        println "[MasterD][FE]--> compiling project at -> ${PROJECT_PATH}\\catalog-fe"
        workingDir "${PROJECT_PATH}"	//vagrant path
        commandLine 'cmd','/c','mvn -T 2 compile -pl catalog-fe,catalog-ui -am -Pcatalog -Dmaven.test.skip'
    }
}
task compileFE(){
    doLast{
        compileFE()
    }
}
def compileBE(){
    exec{
        println "[MasterD][BE]--> compiling project at -> ${PROJECT_PATH}\\catalog-be"
        workingDir "${PROJECT_PATH}"	//vagrant path
        commandLine 'cmd','/c','mvn -T 2 compile -pl catalog-be -Pcatalog -Dmaven.test.skip'
    }
}
task compileBE{
    doLast{
        compileBE()
    }
}

def compile(){
    exec{
        println "[MasterD]--> compiling project at -> ${PROJECT_PATH}"
        workingDir "${PROJECT_PATH}"	//vagrant path
        commandLine 'cmd','/c','mvn -T 2 compile -am -Pcatalog -Dmaven.test.skip'
    }
}

task compile{
    doLast{
        compile()
    }
}
def compileDependencies(){
    def cmd = IS_MVN_INSTALL ? 'install' : 'compile'
    exec{
        println "[MasterD]--> compiling BE dependencies  -> $BE_DEPENDENCIES [ SKIPPING TESTS!! ]"
        workingDir "${PROJECT_PATH}"	//vagrant path
        commandLine 'cmd','/c',"mvn $cmd -pl $BE_DEPENDENCIES -Pcatalog -Dmaven.test.skip" //commandLine 'cmd', '/c','mvn -T 1C package -pl catalog-model,catalog-dao,catalog-be -P catalog -Dmaven.test.skip'
    }
}
task compileDependencies {
    doLast{
        compileDependencies()
    }
}
def compileWar(){
    def cmd = IS_MVN_INSTALL ? 'install' : 'compile'
    exec{
        println "--> compiling project at -> ${PROJECT_PATH}\\catalog-be"
        workingDir "${PROJECT_PATH}"	//vagrant path
        commandLine 'cmd','/c',"mvn -T 1 $cmd war:war -pl catalog-be -Pcatalog -Dmaven.test.skip" //commandLine 'cmd', '/c','mvn -T 1C package -pl catalog-model,catalog-dao,catalog-be -P catalog -Dmaven.test.skip'
    }
}
task compileWar(){
    doLast{
        compileWar()
    }
}

//deprecated - use deployBE()
task be() {
    doLast{
        def started = System.currentTimeMillis();
        exec{
            println "[MasterD]--> copying be... [from $VAGRANT_HOME]"
            workingDir VAGRANT_HOME	//vagrant path
            commandLine 'cmd','/c', 'copy_war_be.bat','localhost' , "$PROJECT_PATH\\catalog-be\\target\\catalog-be*.war" , "$BE_REMOTE/webapps"
            //args = [ ]
        }
        println """
                ****    copying finished in -> ${System.currentTimeMillis() - started}ms         ****
                """
    }
}

task beConfig( ) {
    doLast{
        exec{
            workingDir "${System.env.VAG}"	//vagrant path
            commandLine 'cmd','/c','copy_war_be_with_configuration','localhost' , "$PROJECT_PATH\\catalog-be\\target\\catalog-be*.war" , "$BE_REMOTE/webapps"
            //args = [ ]
        }
    }

}
task feConfig( ) {
    doLast{
        exec{
            workingDir "${System.env.VAG}"	//vagrant path
            commandLine 'cmd','/c','copy_war_fe_with_configuration','localhost' , "$PROJECT_PATH\\catalog-fe\\target\\catalog-fe*.war" , "$FE_REMOTE/webapps"
            //args = [ ]
        }
    }

}

task fe() {
    doLast{
        exec {
            workingDir "${System.env.VAG}"    //vagrant path
            commandLine 'cmd','/c', 'copy_war_fe.bat', 'localhost', "$PROJECT_PATH\\catalog-fe\\target\\catalog-fe*.war", "$FE_REMOTE/webapps"
            //args = [ ]
        }
    }
}

def installAllProject(){
    exec{
        println "[MasterD]--> Compiling&Installing project at -> ${PROJECT_PATH}"
        workingDir "${PROJECT_PATH}"	//vagrant path
        commandLine 'cmd','/c','mvn -T 2 clean install -U -Pcatalog -Dmaven.test.skip'
    }
}
task installAllProject {
    doLast {
        installAllProject()
    }
}

task installAll {
    doLast{
        println '[MasterD]--> Finished!!'
    }
}
installAll.dependsOn { tasks.findAll { task -> task.name.startsWith('install_') } }

def install_BE(){
    exec {
            println '[MasterD][Install]--> Installing BE!!'
            workingDir "${PROJECT_PATH}"
            commandLine 'cmd','/c', 'mvn clean install -pl catalog-be -am -Pcatalog -Dmaven.test.skip'
            //args = [ ]
    }
}

task install_BE() {
    doLast{
        install_BE()
    }
}

def install_FE() {
    exec {
        workingDir "${PROJECT_PATH}"
        commandLine 'cmd','/c', 'mvn clean install -pl catalog-ui,catalog-fe -am -Pcatalog -Dmaven.test.skip'
    }
}
task install_FE() {
    doLast {
        install_FE()
    }
}

def updaterBERapid(){
    /* if ( ticket() > PREVIOUS_BUILD_VAR ){
     PREVIOUS_BUILD_VAR = ticket()*/
    def started = System.currentTimeMillis();
    println "[MasterD][Rapid]--> compiling changes using maven"
    compileWar()
    println "[MasterD][Rapid]--> copying war"
    copyBE() //use this if you want to deploy entire war //hotswap.execute()
    restartBackend()
    println msg(" redeploy finished in -> ${System.currentTimeMillis() - started}ms ")
}
task updaterBERapid(){
    doLast {
        updaterBERapid()
    }
}
def updaterBE(){
    def started = System.currentTimeMillis();
    IS_MVN_INSTALL = pomChanges() ? true :  false
    println "[MasterD]--> compiling changes using maven"
    compileDependencies()
    compileWar()
    println "[MasterD]--> copying war"
    IS_HOTSWAP ? copyExplodedBE() : copyBE() //execute() //use this if you want to deploy entire war //hotswap.execute()
    restartBackend()
    println msg("redeploy finished in -> ${System.currentTimeMillis() - started}ms ")
}
task updaterBE(){
    doLast {
        updaterBE()
    }
}
def copyBEConfiguration(){
/*    execSafe {
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                println msg("Stopping BackEnd Server")
                execute command[BACKEND][STOP]()
            }
        }
    }*/
}
def updaterBEFull(){
    def started = System.currentTimeMillis();
    compile()
    println "[MasterD]--> copying war"
    copyBE() //use this if you want to deploy entire war //hotswap.execute()
    copyBEConfiguration()
    println msg("redeploy finished in -> ${System.currentTimeMillis() - started}ms ")
}
task updaterBEFull(){
    doLast {
        updaterBEFull()
    }
}
def copyFEConfiguration(){
    //todo- implement
}
def updaterFE(){
    def started = System.currentTimeMillis();
    println "[MasterD]--> compiling changes using maven"
    compileFE()
    println "[MasterD]--> copying war"
    copyFE() //.execute() //use this if you want to deploy entire war //hotswap.execute()
    copyFEConfiguration()
    println msg("redeploy finished in -> ${System.currentTimeMillis() - started}ms ")
}
task updaterFE(){
    doLast {
      updaterFE()
    }
}
def stopBackend(){
    execSafe {
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                println msg("Stopping BackEnd Server")
                execute command[BACKEND][STOP]()
            }
        }
    }
}
task stopBackend(){
    doLast {
        stopBackend()
    }
}

def startBackend(){
    execSafe {
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                println msg("[MasterD] starting backend sever")

                execute command[BACKEND][START]()
            }
        }
    }
    println """[MasterD]->  finished !!
					    """
}
task startBackend(){
    doLast{
        startBackend()
    }
}

def restartBackend(){
    execSafe {
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                println msg("[MasterD] restarting backend server")

                execute command[BACKEND][RESTART]()
            }
        }
    }
    println """[MasterD]->  finished !!
					    """
}

def startSecurity(){
    println "[MasterD] starting security&simulator engine"
    execSafe {
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                execute command[SECURITY][START]()
            }
        }
    }
    println """[MasterD]->  finished !!
					    """
}
task startSecurity(){
    doLast {
        startSecurity()
    }
}

def stopSecurity(){
    println "[MasterD] stopping security&simulator engine"
    execSafe {
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                execute command[SECURITY][STOP]()
            }
        }
    }
    println """[MasterD]->  finished !!
					    """
}

task stopSecurity(){
    doLast {
        stopSecurity()
    }
}


//todo- remove this if you want to auto-deploy on every file save
/*
compileJava.doFirst{
    updater?.execute()
}*/

enum STATUS { UP, DOWN , UNKNOWN , UNAVAILABLE }

task health(){
    doLast {
        prepareTray()
    }
}

def execSafe( closure){
   if (!lockObj) {
        [0..4].forEach( {println "Critical ERROR : lock object is not initialized\n\nCritical ERROR : cannot run tasks\n"}() )
        return;
   }
   synchronized (lockObj){
           boolean prev = isHaltHealth.get()
           try {
               isHaltHealth.set(true)
               closure()
           } catch (Exception e) {
               println e
           } finally {
               isHaltHealth.set(prev)
           }
   }
}

def fetchFiles( remote, local ){
    ssh.run {
        session(remotes.vagrant) {
            //execute "cd /home/vagrant/catalog-be/tmp ; ls -lt | grep catalog-be" //todo- use my dates to filter
            def f = get from: remote  , into: local
            println f?.name
            //return f
        }
        //println "fetched files in ${System.currentTimeMillis() - started} ms"
    }

    //return null
}


def killJava(){
    execSafe {
        def res
        ssh.run {
            session( remotes.vagrant ) {
                println """					 *-*-****************************-*-*
								killing all java proccesses
						*-*-****************************-*-*
					"""
                res = execute command[ALL][KILL]()
            }
        }
        println res?.toString()
    }
}

def importNormative(){
    execSafe {
        ssh.run {
            session(remotes.vagrant) {
                println """					 *-*-************************************-*-*
											importNormative
								*-*-************************************-*-*
							"""
                execute "sudo python -v $BE_REMOTE/scripts/import/tosca/importNormativeAll.py"
            }
        }
    }
}

def startAll(){
    def startCassandra = """
                        #!/bin/bash

                        cassandra&
                        elasticsearch -d

                        #Wait until ES is up
                        until curl localhost:9200/_cluster/health;
                        do
                            printf "."
                            sleep 3
                        done

                        # Create Elastic Mapping if not exist in ES
                        createESMapping.sh
                        """
    execSafe {
        ssh.run {
            session(remotes.vagrant) {
                println """					 *-*-************************************-*-*
								starting all SDC services(DB,BE,FE,Webseal)
							*-*-************************************-*-*
				"""
                if ( isProductionVM() ){
                    execute command[DB][START]()
                    Thread.sleep(5000)
                    execute command[CACHING][START]()
                }
                else
                    execute startCassandra
                //[0..4]?.forEach( Thread?.sleep(2000) )
                Thread?.sleep(10000)
                Thread?.sleep(10000)
                execute command[BACKEND][START]()
                execute command[FRONTEND][START]()
                execute command[SECURITY][START]()
            }
        }
    }
}


/*def clearLog(type: Delete){
    delete{
        delete 'C:/ProgramData/all.log'
        followSymlinks = true
    }
}*/
task clearLog(type: Delete){
    doLast{
        delete 'C:/ProgramData/all.log'
        followSymlinks = true
    }
}
def logBE(){
    try{
        println "\n*** logging BE all.log ***\n"

            ssh.run {
                session( remotes.vagrant ) {
                    //String now = execute 'echo \"\$(date +\'%Y_%m_%d\')\"'
                    //println "\n\n*******************************************************\n\n"+now?.toString()
                    clearLog?.execute() //todo- remove this .execute()
                    fetchFiles( '/home/vagrant/catalog-be/logs/SDC/SDC-BE/all.log' , 'C:/ProgramData') //"%USERPROFILE%\AppData\Local\")
                    //project.ext.set( "logFile" , 'C:/ProgramData/all.log' )

                    //				-f /home/vagrant/catalog-fe/logs/*$now.stderrout.log -f /home/vagrant/catalog-be/logs/*$now.stderrout.log -f /home/vagrant/catalog-be/logs/ASDC/ASDC-BE/debug.log*'
                }
            }

        parallel {
            exec {
                //if ( logFile ){
                String notepad = 'C:\\Program Files (x86)\\Notepad++\\notepad++.exe'
                println "logging $logFile to notepad++ [$notepad]"
                commandLine 'cmd','/c' , notepad ,logFile
            }
        }
    }catch(Exception e){
        println "cannot open logs!!!"
        e.printStackTrace()
    }
}
task logBE(){
    doLast{
        logBE()
    }
}

def toggleHealthPolling(){
    isHaltHealth.set(!isHaltHealth.get())
}
//converts predefined icon to Image
def Image convert( imageName ){
    String encodedimage = project.ext.get(imageName);
    byte[] byteImage = encodedimage?.split(',')[1]?.decodeBase64()
    Image image = ImageIO.read(new ByteArrayInputStream(byteImage));
}

def refreshMenu(String imageName){
    switch( imageName ) {
        case 'unavailableImg' : toggleHealthString = "Resume Health";  break;
        default : toggleHealthString = "Halt Health";
    }
    if (((MenuItem)toggleHealthItemView).getLabel() != toggleHealthString)
        ((MenuItem)toggleHealthItemView).setLabel(toggleHealthString);
}
def startDB(){
        println "[MasterD] Starting database.."
        execSafe {
            ssh.settings {
                knownHosts = allowAnyHosts
            }
            ssh.run {
                session(remotes.vagrant) {
                    execute command[DB][START]()
                }
            }
        }
}
task startDB(){
    doLast {
        startDB()
    }
}
def stopDB(){
    execSafe {
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                execute command[DB][STOP]()
            }
        }
    }
}
task stopDB(){
    doLast {
        stopDB()
    }
}
def startFE(){
    execSafe {
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                execute command[FRONTEND][START]()
            }
        }
    }
}
task startFE(){
    doLast {
        startFE()
    }
}
def stopFE(){
    execSafe {
        ssh.settings {
            knownHosts = allowAnyHosts
        }
        ssh.run {
            session(remotes.vagrant) {
                execute command[FRONTEND][STOP]()
            }
        }
    }
}
task stopFE(){
    doLast {
        stopFE()
    }
}

def ActionListener newListener( closure  ){
    ActionListener listener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            try {
                    closure()
            } catch (AWTException e1) {
                System.err.println(e1);
            }
        }
    }

    listener
}

ext.updateTray = { STATUS status ->
    lastStatus = status
    if (SystemTray.isSupported()) {
        // get the SystemTray instance
        SystemTray tray = SystemTray.getSystemTray();
        // load an image
        String imageName = status==STATUS.UP ? (Math.random()>0.5 ?'okImg1':'okImg2') : status==STATUS.UNAVAILABLE ? 'unavailableImg' : status==STATUS.DOWN ? 'errorImg' : 'warnImg'
        Image image = convert imageName
        if (trayIcon != null) {
            trayIcon.setImage(image)
            refreshMenu(imageName);
            return ;
        }
        //region  -> Menu UI
        // create a popup menu
        PopupMenu popup = new PopupMenu();
        // create menu item for the default action

        MenuItem hotswapItem = new MenuItem("===> WAR <===");
        hotswapItem.setFont(new Font("MONOSPACED" , Font.BOLD ,15f ))

        //region Multilevel Menus
        Menu deployMasterMenu = new Menu("DeployMaster");
        Menu backendMenu = new Menu("Backend");
        Menu frontendMenu = new Menu("Frontend");
        Menu dbMenu = new Menu("Database");
        Menu securityMenu = new Menu("Security");
        try{
            deployMasterMenu.setFont(new Font("Cooper Black" ,Font.BOLD ,14f ))
            backendMenu.setFont(new Font("Cooper Black" ,Font.PLAIN ,13f ))
            frontendMenu.setFont(new Font("Cooper Black" ,Font.PLAIN ,13f ))
            dbMenu.setFont(new Font("Cooper Black" ,Font.PLAIN ,13f ))
            securityMenu.setFont(new Font("Cooper Black" ,Font.PLAIN ,13f ))
        }catch(Exception e){
            println e
        }

        //DeployMaster Menu
        MenuItem updaterBeWithDependenciesItem = new MenuItem("[BE] Quick Compile -> Deploy");
        MenuItem updaterFullBeItem = new MenuItem("[BE] Full Install  -> Deploy");
        MenuItem updaterFeItem = new MenuItem("[FE] Quick Compile -> Deploy");
        MenuItem updaterFullFeItem = new MenuItem("[FE] Full Install -> Deploy");

        //Menu UI build

        deployMasterMenu.add(updaterFullBeItem);
        deployMasterMenu.add(updaterBeWithDependenciesItem);

        deployMasterMenu.addSeparator();
        deployMasterMenu.add(updaterFullFeItem);
        deployMasterMenu.add(updaterFeItem);


        //BE menu
        MenuItem startItem = new MenuItem("[BE] Start");
        MenuItem stopItem = new MenuItem("[BE] Stop BackEnd");
        MenuItem copyBeWarItem = new MenuItem("[BE] Copy War");
        backendMenu.add(startItem);
        backendMenu.add(stopItem);
        (isOnapVM()) ?: backendMenu.add(copyBeWarItem);

        //FE menu
        MenuItem startFEItem = new MenuItem("[FE] Start");
        MenuItem stopFEItem = new MenuItem("[FE] Stop");
        MenuItem copyFeWarItem = new MenuItem("[FE] Copy War");
        frontendMenu.add(startFEItem);
        frontendMenu.add(stopFEItem);
        (isOnapVM()) ?: frontendMenu.add(copyFeWarItem);

        //DB menu
        MenuItem startDBItem = new MenuItem("[DB] Start");
        MenuItem stopDBItem = new MenuItem("[DB] Stop");
        MenuItem backupDBItem = new MenuItem("[DB] Backup");
        MenuItem restoreDBItem = new MenuItem("[DB] Restore");
        dbMenu.add(startDBItem);
        dbMenu.add(stopDBItem);
        dbMenu.add(backupDBItem);
        dbMenu.add(restoreDBItem);
        //endregion
        //Security Menu
        MenuItem startSecurityItem = new MenuItem("[Security] Start");
        MenuItem stopSecurityItem = new MenuItem("[Security] Stop");
        securityMenu.add(startSecurityItem)
        securityMenu.add(stopSecurityItem)

        MenuItem killItem = new MenuItem("Kill All");
        MenuItem startAllItem = new MenuItem("Start All");
        MenuItem importItem = new MenuItem("Import Normative");
        MenuItem healthInfoItem = new MenuItem("[Info] Health");
        MenuItem toggleHealthItem = new MenuItem(toggleHealthString);
        MenuItem logsItem = new MenuItem("Logs [Beta]");
        MenuItem exitItem = new MenuItem("Exit");

        toggleHealthItemView = toggleHealthItem;

        (isOnapVM()) ?: popup.add(hotswapItem);
        (isOnapVM()) ?:popup?.addSeparator();
        (isOnapVM()) ?: popup.add(deployMasterMenu);
        (isOnapVM()) ?:popup?.addSeparator();
        popup.add(backendMenu)
        popup.add(frontendMenu)
        (isOnapVM()) ?: popup.add(dbMenu)
        popup?.addSeparator();
        popup?.add(securityMenu)
        popup?.addSeparator();
        popup.add(startAllItem);
        popup.add(killItem);
        popup?.addSeparator();
        popup.add(toggleHealthItem);
        popup.add(healthInfoItem);
        (isOnapVM()) ?:popup?.addSeparator();
        (isOnapVM()) ?: popup.add(importItem);
        (isOnapVM()) ?: popup.add(logsItem);
        popup?.addSeparator();
        popup.add(exitItem);
        //endregion UI
        // construct a TrayIcon
        trayIcon = new TrayIcon(image, "HealthTray", popup);

        //region -> Button actions
        def listenerHotswap = newListener { project.ext.set("IS_HOTSWAP", !IS_HOTSWAP); hotswapItem?.setLabel( IS_HOTSWAP ? "==> HotSwap <==" : "===> WAR <===")   }
        // create a action listener to listen for default action executed on the tray icon
        def listenerFullBE = newListener { parallel { install_BE(); IS_HOTSWAP ? copyExplodedBE() : copyBE(); restartBackend() } }
        def listenerFullFE = newListener { parallel { install_FE(); copyFE() } }
        ActionListener listenerFE = newListener { parallel { updaterFE() } }
        ActionListener listenerBE = newListener { parallel { updaterBE() } }
        ActionListener exitListener = newListener {
                    executor?.isShutdown() ?: executor?.shutdown()
                    tray.remove(trayIcon);
                    project.ext.set("isStopHealthCheck", true)
                    println "Shutting down.. bye bye.."
                }
        ActionListener stopBackendListener = newListener { stopBackend() }
        ActionListener startBEListener = newListener { parallel { startBackend() } }
        ActionListener killJavaListener = newListener { killJava() }

        ActionListener startAllListener = newListener { parallel { startAll() } }

        ActionListener startSecurityListener = newListener { startSecurity() }
        ActionListener stopSecurityListener = newListener { stopSecurity() }

        ActionListener listener5 = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    parallel { importNormative() }
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        };

        ActionListener listener6 = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    parallel { healthPopup() }
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        };

        ActionListener listener7 = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    logBE()//tasks.logger.execute()
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        };
        ActionListener listener8 = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    toggleHealthPolling()//tasks.logger.execute()
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        };
        ActionListener copyBeWarListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    parallel { copyBE() }//.execute()//tasks.logger.execute()
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        };

        ActionListener startDBListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    parallel {
                        startDB()
                    }//tasks.logger.execute()
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        }

        ActionListener stopDBListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    stopDB()//tasks.logger.execute()
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        }

        ActionListener dbBackupListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    parallel {
                        backupDB()//tasks.logger.execute()
                    }
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        }

        ActionListener feStartListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    parallel {
                        startFE()
                    }//tasks.logger.execute()
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        }

        ActionListener feStopListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    stopFE()//tasks.logger.execute()
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        }

        ActionListener feCopyListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    parallel {
                        copyFE() //.execute()//tasks.logger.execute()
                    }
                } catch (AWTException e1) {
                    System.err.println(e1);
                }
            }
        }


        //def listenerFullModules = newListener { parallel { installAllProject() } }
        //region -> Button<=Listener
        hotswapItem.addActionListener(listenerHotswap)
        updaterFeItem.addActionListener(listenerFE)
        updaterFullBeItem.addActionListener( listenerFullBE )
        updaterBeWithDependenciesItem.addActionListener( listenerBE )
        updaterFullFeItem.addActionListener( listenerFullFE )
        stopItem.addActionListener(stopBackendListener)
        startItem.addActionListener(startBEListener)
        copyBeWarItem.addActionListener(copyBeWarListener);
        startSecurityItem.addActionListener(startSecurityListener)
        stopSecurityItem.addActionListener(stopSecurityListener)
        killItem.addActionListener(killJavaListener)
        startAllItem.addActionListener(startAllListener)
        importItem.addActionListener(listener5)
        healthInfoItem.addActionListener(listener6)
        toggleHealthItem.addActionListener(listener8)
        logsItem.addActionListener(listener7)
        exitItem.addActionListener(exitListener)

        startDBItem.addActionListener( startDBListener )
        stopDBItem.addActionListener( stopDBListener )
        backupDBItem.addActionListener( dbBackupListener )
        copyFeWarItem.addActionListener( feCopyListener )
        startFEItem.addActionListener( feStartListener )
        stopFEItem.addActionListener( feStopListener )
        //endregion
        //endregion
        // set the TrayIcon properties

        // ...
        // add the tray image
        try {
            tray.add(trayIcon);

        } catch (AWTException e) {
            System.err.println(e);
        }
        // ...
    } else {
        println "Java TrayIcon Option is not supported in your System, try enabling it. Bye Bye"
    }

}

def prepareTray(){
    long UPDATE_THRESHOLD = 3500
    float SCALAR = 1
    ssh.settings {
        knownHosts = allowAnyHosts
    }
    while(!isStopHealthCheck) {
        if (!isHaltHealth.get()) {    //if await or await is more then 60 second return health check
            ssh.run {
                session(remotes.vagrant) {
                    try {
                        def healthOutput = execute command[ALL][HEALTH]()
                        if (healthOutput?.contains("Failed command .* with status 7") || healthOutput?.contains("Problem accessing /sdc2/rest/healthCheck"))
                            updateTray(STATUS.DOWN)
                        def statusCollecion = healthOutput?.findAll "\"healthCheckStatus\": \".*\""
                        def upCount = statusCollecion?.count { it?.contains("UP") }
                        def downCount = statusCollecion?.count { it?.contains("DOWN") }
                        def uknownCount = (statusCollecion?.size() - upCount) - downCount
                        println " UP -> $upCount | downCount=$downCount | uknownCount=$uknownCount "
                        (uknownCount > 0 || (downCount > 0 && upCount > 0)) ? updateTray(STATUS.UNKNOWN) : ((upCount > 0) ? updateTray(STATUS.UP) : updateTray(STATUS.DOWN))
                        SCALAR = 1
                    } catch (Exception e) {
                        updateTray(STATUS.DOWN)
                        println e
                        SCALAR = Math.min(SCALAR * 1.1, 5) //slow down on errors
                    }
                    //green color effects
                    if (lastStatus && lastStatus == STATUS.UP) {
                        trayIcon.setImage(convert(Math.random() > 0.5 ? 'okImg1' : 'okImg2'))
                        //randomly green change color
                    }
                    Thread.yield()
                    Thread?.sleep((long) (UPDATE_THRESHOLD * SCALAR))
                }
            }
        }else{
            updateTray(STATUS.UNAVAILABLE)
            Thread.yield()
        }
    }
}

def healthPopup(){
    ssh.run {
        session(remotes.vagrant) {
            def healthOutput = execute command[ALL][HEALTH]()
            JOptionPane.showMessageDialog(null,
                    healthOutput,
                    "HEALTH",
                    JOptionPane.INFORMATION_MESSAGE);
        }
    }
}

project.ext.set("msg", { content -> """
                        ************************************************************************************************
                        ************************************************************************************************
                        *******                                                                                *********
                        **************                                                                  ****************
                                                $content      

                        ************************************************************************************************
                        ************************************************************************************************
                        """} )