description 'Package Node as stand-alone application'

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

ext {
    outputDir = "$buildDir/corda"
    tarballDir = "$buildDir/distribution"
}

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')
        }
    }
    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"
}

def isLinux = System.properties['os.name'].toLowerCase().contains('linux')
def isMac = System.properties['os.name'].toLowerCase().contains('mac')
if (isLinux || isMac) {
    println("Detected *nix system, enabling distribution creation")
    task buildLauncher(type: Exec, dependsOn: [copyLauncherLibs]) {
        description 'Build Launcher executable'

        def relativeDir
        if (isLinux)
            relativeDir = "launcher"
        else
            relativeDir = "launcher.app/Contents"

        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 launcherLib = copyLauncherLibs.destinationDir
            def srcfiles = []
            def launcherClasspath = []

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

            commandLine = [
                    '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'

        into(outputDir)

        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(project(':docs').buildDir) {
            into("docs")
        }

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

    task buildCordaTarball(type: Tar, dependsOn: [buildNode]) {
        from outputDir
        compression = Compression.BZIP2
        baseName = 'corda-enterprise-distribution'
        destinationDir = file(tarballDir)
        extension = "tar.bz2"

        doLast{
            println("Distribution tarball available at:")
            println("${tarballDir}/${baseName}.${extension}")
        }
    }
} else {
    println("Not running on *nix, disabling distribution generation")
}