import org.gradle.internal.jvm.Jvm
import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'net.corda.plugins.publish-utils'


description 'Package Node as stand-alone application'

evaluationDependsOn(":node")
evaluationDependsOn(":docs")
evaluationDependsOn(":launcher")

ext {
    outputDir = "$buildDir/corda"
    tarballDir = "$buildDir/distribution"
    tarballBaseName = 'corda-enterprise-distribution'
    tarballExtension = "tar.bz2"
}

def tmpDir = "${buildDir}/tmp/"

configurations {
    launcherClasspath
}

// Define location of predefined startup scripts, license and README files
sourceSets {
    binFiles {
        resources {
            srcDir file('src/main/resources/bin')
        }
    }
    installerFiles {
        resources {
            srcDir file('src/main/resources/installer')
        }
    }
    readmeFiles {
        resources {
            srcDir file('src/main/resources/readme')
        }
    }
}

// Runtime dependencies of launcher
dependencies {
    compile project(':node')
    launcherClasspath project(':launcher')
    launcherClasspath "org.slf4j:jul-to-slf4j:$slf4j_version"
    launcherClasspath "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}"
    launcherClasspath "org.apache.logging.log4j:log4j-web:${log4j_version}"

    // Required by JVM agents:
    launcherClasspath "com.google.guava:guava:$guava_version"
    launcherClasspath "de.javakaffee:kryo-serializers:0.41"
}

task copyLauncherLibs(type: Copy, dependsOn: [project(':launcher').jar]) {
    from configurations.launcherClasspath
    into "$buildDir/tmp/launcher-lib"
}

if (Os.isFamily(Os.FAMILY_UNIX)) {
    println("Detected *nix system, enabling distribution creation")


    task buildLauncher(type: Exec, dependsOn: [copyLauncherLibs]) {
        description 'Build Launcher executable'

        def relativeDir = "launcher"


        def extraArgs = [
                "-BjvmOptions=-javaagent:../../lib/quasar-core-${quasar_version}-jdk8.jar=${project(':node:capsule').quasarExcludeExpression}",
                '-BuserJvmOptions=-Xmx=4g',
                '-BuserJvmOptions=-XX\\:=+UseG1GC',
                "-BjvmProperties=java.system.class.loader=${project(':launcher').loaderClassName}"
        ]

        ext {
            launcherBinDir = "${tmpDir}/bundles/$relativeDir"
        }

        workingDir project.projectDir

        doFirst {
            def currentJvmPathContainsOpenJDK = Jvm.current().javaHome.absolutePath.toLowerCase().contains("openjdk")
            if (currentJvmPathContainsOpenJDK) {
                throw new BuildCancelledException("Building installer using an openJDK JDK")
            }

            def launcherLib = copyLauncherLibs.destinationDir
            def srcfiles = []
            def launcherClasspath = []

            fileTree(launcherLib).forEach({ file ->
                srcfiles.add("-srcfiles")
                srcfiles.add(file.name)
                launcherClasspath.add(file.name)
            })

            commandLine = [
                    '/usr/bin/env',
                    'javapackager',
                    '-deploy',
                    '-nosign',
                    '-native', 'image',
                    '-outdir', "$tmpDir",
                    '-outfile', 'launcher',
                    '-name', 'launcher',
                    "-BmainJar=${project(':launcher').jar.archiveName}",
                    "-Bclasspath=${launcherClasspath.join(":")}",
                    '-appclass', "${project(':launcher').launcherClassName}",
                    '-srcdir', "$launcherLib"
            ] + srcfiles + extraArgs
        }

        // Add configuration for running Node application
        doLast {
            def nodeClasspath = []
            def libRelPath = "../lib/"

            project(':node').configurations.runtime.forEach({ file ->
                nodeClasspath.add(file.getName())
            })

            nodeClasspath.add(project(':node').jar.archivePath.getName())

            new File("${launcherBinDir}/runtime.properties").text = [
                    "libpath=${libRelPath}",
                    "classpath=${nodeClasspath.join(':')}",
                    "plugins=./drivers:./cordapps"].join("\n")
        }
    }

    task buildNode(type: Copy, dependsOn: [buildLauncher, project(':docs').tasks['makeDocs'], project(':node').tasks['jar']]) {
        description 'Build stand-alone Corda Node distribution'

        def dir = file("$outputDir/corda-enterprise")
        into(dir)

        from(buildLauncher.launcherBinDir) {
            into("launcher")
        }

        from(project(':node').configurations.runtime) {
            into("lib")
        }

        from(project(':node').jar.archivePath) {
            into("lib")
        }

        from(sourceSets.binFiles.resources) {
            into("bin")
        }

        from(sourceSets.readmeFiles.resources) {
            into(".")
        }

        from(file("src/main/resources/license/LICENSE")) {
            into(".")
        }

        doLast {
            new File("${dir}/cordapps").mkdirs()
            new File("${dir}/drivers").mkdirs()
            println("Stand-alone Corda Node application available at:")
            println("${dir}")
        }
    }

    task buildCordaTarball(type: Tar, dependsOn: [buildNode]) {

        from outputDir
        compression = Compression.BZIP2
        baseName = tarballBaseName
        destinationDir = file(tarballDir)
        extension = tarballExtension

        doLast {
            println("Distribution tarball available at:")
            println("${tarballDir}/${archiveName}")
        }
    }

    task prepareInstallerEnvironment(type: Copy, dependsOn: buildCordaTarball) {
        into(tarballDir)
        from(sourceSets.installerFiles.resources) {
            into("installer")
        }
    }

    task embedLicense(type: Exec, dependsOn: [prepareInstallerEnvironment]) {
        commandLine "bash", "-c", "sed -i -e '/QQ_LICENSE_FILE_QQ/{r src/main/resources/license/LICENSE' -e 'd}' $tarballDir/installer/installer.sh"
    }

    task embedTarball(type: Exec, dependsOn: [embedLicense]) {
        commandLine "bash", "-c", "cat ${tarballDir}/${buildCordaTarball.archiveName} >> $tarballDir/installer/installer.sh"
    }

    task buildInstaller(dependsOn: [embedTarball])

    def installerFile = file("$tarballDir/installer/installer.sh")

    def installerArtifact = artifacts.add("publish", installerFile) {
        type "sh"
        builtBy(buildInstaller)
    }

    publish {
        name 'corda-installer'
        disableDefaultJar = true
    }



} else {
    println("Not running on *nix, disabling distribution generation")
}