/*
 * Copyright (c) 2017. NanoString Technologies, Inc.
 */

plugins {
    id 'java'
    id 'application'
    id 'org.hidetake.ssh' version '2.9.0'
    id 'com.bmuschko.docker-remote-api' version '4.4.0'
    id 'com.bmuschko.docker-java-application' version '4.4.0'
}

group 'com.nanostring'
version '0.0.1-SNAPSHOT'

sourceCompatibility = 1.8
targetCompatibility = 1.8

mainClassName = 'com.nanostring.pluto.Main'

ext {
    profile = project.hasProperty('profile') ? project.profile : 'dev'
}

ssh.settings {
    knownHosts = allowAnyHosts
}

remotes {
    stg {
        role 'stgServers'
        host = '212.47.242.128'
        user = 'devops'
        password = 'Power$14'
    }
}

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "https://nexus.bedatadriven.com/content/groups/public" }
    maven { url 'http://ec2-18-233-224-170.compute-1.amazonaws.com:8080/repository/release/' }
    jcenter()
}

dependencies {
    //security
    compile group: 'org.pac4j', name: 'spark-pac4j', version: '3.0.0'
    compile group: 'org.pac4j', name: 'pac4j-oidc', version: '3.8.3'
    compile group: 'com.nanostring', name: 'oidc-utils', version: '0.1.7'

    compile "com.nanostring:properties-loader:0.1.0"

    compile "com.sparkjava:spark-core:2.7.2"
    compile group: 'com.google.code.gson', name: 'gson', version: '2.8.2'
    compile group: 'com.google.inject', name: 'guice', version: '4.1.0'

    compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
    compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.9.1'
    compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.9.1'

    compile group: 'org.sql2o', name: 'sql2o', version: '1.6.0-RC3'
//    compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.44'
    compile group: 'org.postgresql', name: 'postgresql', version: '42.2.2'

    compile group: 'javax.validation', name: 'validation-api', version: '2.0.0.Final'
    compile group: 'org.hibernate.validator', name: 'hibernate-validator', version: '6.0.2.Final'
    compile group: 'org.hibernate.validator', name: 'hibernate-validator-annotation-processor', version: '6.0.2.Final'
    compile group: 'javax.el', name: 'javax.el-api', version: '3.0.0'
    compile group: 'org.glassfish', name: 'javax.el', version: '3.0.0'

    compile group: 'com.opencsv', name: 'opencsv', version: '4.0'
    compile group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.220'
    compile group: 'net.coobird', name: 'thumbnailator', version: '0.4.8'
//    compile "org.renjin:renjin-script-engine:0.8.2472"
//    compile "org.renjin:renjin-script-engine:0.9.2692"
//    compile "org.renjin.cran:irlba:2.3.2-b9"

    compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.0'

//    compile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.25.1'

    compile group: 'org.jboss.resteasy', name: 'resteasy-client', version: '3.6.2.Final'

    compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'

    compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.2'
    compile group: 'org.apache.commons', name: 'commons-math3', version: '3.6'

    compile group: 'org.apache.xmlgraphics', name: 'batik-svg-dom', version: '1.9'
    compile group: 'org.apache.xmlgraphics', name: 'batik-svggen', version: '1.9'

//    testCompile group: 'junit', name: 'junit', version: '4.12'

    compile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.4.0'

    // to resolve issue 'junit5 tests are not shown in test view' (gradle junit 5: test events were not received)
    // https://youtrack.jetbrains.com/issue/IDEA-188404?_ga=2.84463964.439431514.1568366554-1542311542.1568198543&_gac=1.220408108.1568198543.EAIaIQobChMIs4vM3srI5AIVh-maCh0LAAFsEAAYASAAEgKGt_D_BwE
    test.useJUnitPlatform()
    testImplementation "org.junit.jupiter:junit-jupiter-params:5.4.0"
    testImplementation "org.junit.jupiter:junit-jupiter-api:5.4.0"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.4.0"
    testCompile group: 'org.mockito', name: 'mockito-core', version: '2.1.0'
    testCompile group: 'com.opentable.components', name: 'otj-pg-embedded', version: '0.13.1'
}

compileJava {
    doLast {
        if (project.hasProperty('incrementBuildNumber') && 'on'.equalsIgnoreCase(project.property('incrementBuildNumber'))) {

            println 'Increment build number'

            def versionPropsFile = file('src/main/resources/version.properties')

            if (versionPropsFile.canRead()) {
                def Properties versionProps = new Properties()

                versionProps.load(new FileInputStream(versionPropsFile))

                def name = versionProps['version.number']
                def build = versionProps['version.build'].toInteger() + 1

                versionProps['version.build']=build.toString()
                versionProps.store(versionPropsFile.newWriter(), null)
            }
            else {
                throw new GradleException("Could not read version.properties")
            }
        }
    }
}

jar {
    if (!'dev'.equalsIgnoreCase(profile))
        exclude('local.properties')

    from {
        (configurations.runtime).collect {
            it.isDirectory() || it.name.endsWith('.pom') ? it : zipTree(it)
        }
    }
    manifest {
        attributes("Main-Class": mainClassName )
    }
}

// DOCKERs

import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import com.bmuschko.gradle.docker.tasks.image.DockerSaveImage

docker {
//    url = 'tcp://127.0.0.1:2375'
}

// DOCKER app tasks

task zipAndCopyFrontToDocker(type: Zip) {
    doFirst {
        println 'Zip & Copy Frontent to docker/target'
    }

    archiveFileName = "front.zip"
    destinationDirectory = file("docker_ns/target")

    from "frontend/dist"
}

task copyJarToDocker(type: Copy) {
    doFirst {
        println 'Copy Jar to docker/target'
    }

    from "$buildDir/libs"
    include "**/*.jar"
    into "docker_ns/target"
}

task copyDockerInitialDbScript(type: Copy) {
    println 'Copy db/initial.postgresql.dsp.sql to docker_db/assets/'

    from "db"
    include '*.postgresql.dsp.sql'
    into 'docker_db/assets/'
    rename { String fileName ->
        fileName.replace("initial.postgresql.dsp.sql", "initial.postgresql.sql")
    }
}

task buildDocker(type: DockerBuildImage) {
    doFirst {
        println 'Build docker started'
    }

    doLast {
        println 'Build docker completed'
    }

    dependsOn ':copyJarToDocker'
    dependsOn ':zipAndCopyFrontToDocker'

    inputDir = file('docker_ns')
    tags.add('pluto:latest')
}

task saveDocker(type: DockerSaveImage) {
    doFirst {
        println 'Save docker started'
    }
    doLast {
        println 'Save docker completed'
    }

    destFile = new File('docker_ns','pluto-docker-image.tar')
    repository = 'pluto'
    tag = 'lattest'
}

// DOCKER DB tasks

task buildDockerDB(type: DockerBuildImage) {
    doFirst {
        println 'Build docker started'
    }

    doLast {
        println 'Build docker completed'
    }

    dependsOn ':copyDockerInitialDbScript'

    println 'done.'

    inputDir = file('docker_db')
    tags.add('pluto_db:latest')
}

// test pretty logging (origin https://gist.github.com/lwasyl/6ae0b8a66903729033e18ffc7a503597#file-fancy_logging_original-gradle)
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent

tasks.withType(Test) {
    testLogging {

        // set options for log level LIFECYCLE
        events TestLogEvent.FAILED,
                TestLogEvent.PASSED,
                TestLogEvent.SKIPPED,
                TestLogEvent.STANDARD_OUT

        exceptionFormat TestExceptionFormat.FULL
        showExceptions true
        showCauses true
        showStackTraces true

        // set options for log level DEBUG and INFO
        debug {
            events TestLogEvent.STARTED,
                    TestLogEvent.FAILED,
                    TestLogEvent.PASSED,
                    TestLogEvent.SKIPPED,
                    TestLogEvent.STANDARD_ERROR,
                    TestLogEvent.STANDARD_OUT

            exceptionFormat TestExceptionFormat.FULL
        }

        info.events = debug.events
        info.exceptionFormat = debug.exceptionFormat

        afterSuite {
            desc, result ->
                if (!desc.parent) { // will match the outermost suite
                    def output = "Results: ${result.resultType} (${result.testCount} tests, " +
                            "${result.successfulTestCount} successes, " +
                            "${result.failedTestCount} failures, " +
                            "${result.skippedTestCount} skipped)"
                    def startItem = '|  ', endItem = '  |'
                    def repeatLength = startItem.length() + output.length() + endItem.length()

                    println('\n' + ('-' * repeatLength) + '\n' + startItem + output + endItem + '\n' + ('-' * repeatLength))
                }
        }
    }
}

//task stgDeploy {
//
//    task(frontResourcesClear, type: Delete) {
//        println 'Clear old build/stg/front.zip ...'
//
//        delete 'build/stg/front.zip'
//        followSymlinks = true
//
//        println 'done.'
//
//    }.execute()
//
//    task(frontResourcesZip, type: Zip) {
//
//        println 'Archive frontend/dist/ as zip: build/stg/front.zip ...'
//
//        from 'frontend/dist/'
//        include '*'
//        include '*/**' //to include contents of a folders present inside directory
//        archiveName 'front.zip'
//        destinationDir(file('build/stg/'))
//
//        println 'done.'
//
//    }.execute()
//
//    task(deploy) {
//        ssh.run {
//            session(remotes.stg) {
//
//                println 'Start of deploy to STG...'
//
//                def remoteDirPath = '/home/devops/distrib/'+new Date().format('yyyyMMdd_HH_mm_ss')
//
//                println 'Create remote dir: '+remoteDirPath+' ...'
//
//                def result = execute 'mkdir -p '+remoteDirPath
//
//                println 'done.'
//
//                FileTree stgFrontTree = fileTree(dir: 'build/stg')
//
//                println 'Copy content of local: '+stgFrontTree+' to remote: '+remoteDirPath
//
//                put from: stgFrontTree.getFiles(), into: remoteDirPath
//
//                println 'done.'
//
//                FileTree stgJarTree = fileTree(dir: 'build/libs')
//
//                println 'Copy content of local: '+stgJarTree+' to remote: '+remoteDirPath
//
//                put from: stgJarTree.getFiles(), into: remoteDirPath
//
//                println 'done.'
//
//                println 'Start remote redeploy'
//
//                execute '/home/devops/pluto/deploy.sh'
//
//                println 'done.'
//
//                println 'End of deploy to STG.'
//            }
//        }
//
//    }.execute()
//}
//
//task stgDocker {
//
//    task(frontResourcesClear, type: Delete) {
//        println 'Clear old build/stg/front.zip ...'
//
//        delete 'build/stg/front.zip'
//        followSymlinks = true
//
//        println 'Clear old docker/target/* ...'
//
//        delete fileTree('docker/target'){
//            include '*.jar'
//            include '*.zip'
//        }
//
//        println 'done.'
//
//    }.execute()
//
//    task(frontResourcesZip, type: Zip) {
//
//        println 'Archive frontend/dist/ as zip: build/stg/front.zip ...'
//
//        from 'frontend/dist/'
//        include '*'
//        include '*/**' //to include contents of a folders present inside directory
//        archiveName 'front.zip'
//        destinationDir(file('build/stg/'))
//
//        println 'done.'
//
//    }.execute()
//
//    task(frontResourcesDockerTarget, type: Copy) {
//        println 'Copy build/stg/front.zip, build/libs/*.jar to docker/target/'
//
//        from('build/stg/') {
//            include '*.zip'
//        }
//
//        from('build/libs') {
//            include '*.jar'
//        }
//
//        into 'docker/target'
//
//        println 'done.'
//
//    }.execute()
//
////    task(frontResourcesDockerMysql, type: Copy) {
////        println 'Copy db/initial.mysql.sql to docker/asstets/mysql/'
////
////        from('db') {
////            include '*.sql'
////        }
////
////        into 'docker/assets/mysql'
////
////        println 'done.'
////
////    }.execute()
//
//    task(frontResourcesDockerPostgres, type: Copy) {
//        println 'Copy db/initial.postgresql.sql to docker/assets/'
//
//        from('db') {
//            include '*.postgresql.sql'
//        }
//
//        into 'docker/assets/'
//
//        println 'done.'
//
//    }.execute()
//
//}
//
//task incrementBuildNumber {
//
//    task(increment) {
//
//        def versionPropsFile = file('src/main/resources/version.properties')
//
//        if (versionPropsFile.canRead()) {
//            def Properties versionProps = new Properties()
//
//            versionProps.load(new FileInputStream(versionPropsFile))
//
//            def name = versionProps['version.number']
//            def build = versionProps['version.build'].toInteger() + 1
//
//            versionProps['version.build']=build.toString()
//            versionProps.store(versionPropsFile.newWriter(), null)
//
//    //        defaultConfig {
//    //            applicationId "com."
//    //            versionName name
//    //        }
//        }
//        else {
//            throw new GradleException("Could not read version.properties")
//        }
//
//    }.execute()
//
//    compileJava.doLast {
//       tasks.increment.execute()
//    }
//}

