// The MIT License (MIT)
//
// Copyright (c) 2007-2018 Broad Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
apply plugin: 'java'
import org.apache.tools.ant.filters.ReplaceTokens

ext.moduleName = 'org.igv'
ext.mainClassName = 'org.broad.igv.ui.Main'

// Put the Java 11 build into a special dir to avoid accidental collisions.
// Despite this, it is recommended that Java 8 vs. 11 builds be run in different locations.
buildDir = 'build_java11'

sourceSets {
    main {
        java {
            srcDirs = ['src/main/java', 'src/main/java11']
        }
        resources {
            srcDirs = ['src/main/resources', 'src/main/resources-jlfgr-1_0']
            exclude "**/*LICENSE*", "**/META-INF"
        }
    }
}
configurations {
    jarsForClasspath
}

dependencies {
    compile fileTree(dir: 'lib', include: '*.jar')
    testCompile fileTree(dir: 'test/lib', include: '*.jar')
}

task wrapper(type: Wrapper) {
    gradleVersion = '4.10.2'
}

// Gradle bug prevents us from generating Java 11 bytecode: https://github.com/gradle/gradle/issues/5120
// Workaround is to target Java 10 for now.
sourceCompatibility = 10
targetCompatibility = 10

processResources {
    // Set the current timestamp for release builds; pass in a blank property to enable (i.e. -Ptimestamp="" at CLI)
    if (timestamp.equals("")) { timestamp = new Date().format("MM/dd/yyyy hh:mm aa") }

    filesMatching('resources/about.properties') {
        filter (ReplaceTokens,
                tokens: [ VERSION: version, BUILD: buildNumber, DEFAULT_MASTER_RESOURCE_URL: dataServerUrl,
                          TIMESTAMP: timestamp, DEVELOPMENT: development ])
    }
}

jar {
    archiveName = 'igv.jar'
    manifest {
        attributes(
            "Permissions": "all-permissions",
            "Application-Name": "IGV",
            "Built-By": System.getProperty('user.name'),
            "Main-Class": mainClassName,
        )
    }
}

compileJava {
    inputs.property("moduleName", moduleName)
    doFirst {
        options.compilerArgs = [
            '--module-path', classpath.asPath,
        ]
        classpath = files()
    }
}

tasks.withType(Test) {
    systemProperties = System.getProperties()
    systemProperties['java.awt.headless'] = 'true'
    systemProperties['make.fail'] = 'false'
    systemProperties['include.longrunning'] = 'false'
    systemProperties['ignore.ioexceptions'] = 'false'
    maxHeapSize = '2000m'
    maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
}

compileTestJava {
    inputs.property("moduleName", moduleName)
    doFirst {
        options.compilerArgs = [
            '--module-path',  classpath.asPath, 
            '--add-modules', 'junit',
            '--add-modules', 'fest.swing',
            '--patch-module', "$moduleName=" + files(sourceSets.test.java.srcDirs).asPath, 
        ]
        classpath = files()
    }
}

test {
    inputs.property("moduleName", moduleName)
    doFirst {
        jvmArgs = [
            '-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize',
            '--module-path',  classpath.asPath, 
            '--add-modules', 'junit', 
            '--add-modules', 'fest.swing', 
            '--add-modules', 'ALL-MODULE-PATH',
            '--add-reads', "$moduleName=junit", 
            '--add-reads', "$moduleName=fest.swing",
            '@scripts/java11/test_suite.args',
            '--patch-module', "$moduleName=" + files(sourceSets.test.java.outputDir, sourceSets.main.output.resourcesDir).asPath, 
        ]
        classpath = files()
    }
}

task createDist(type: Copy, dependsOn: jar)  {
    from ("web/IGV_64.png")
    from ('scripts/java11') {
        include '*.bat'
        include '*.sh'
        include 'igv.command'
        include 'igv.args'
        include 'readme.txt'
        include 'igvtools*'
    }
    with copySpec {
        from ("${buildDir}/libs")
        from ("lib") { include '*.jar' }
        into "lib"
    }
    with copySpec { from ("genomes/sizes") { } into "lib/genomes" }

    into "${buildDir}/IGV-dist"
}

task createDistZip(type: Zip, dependsOn: createDist) {
    archiveName = "IGV_${version}.zip"
    destinationDir = file("${buildDir}/distZip")
    baseName = "IGV"
    from ("${buildDir}/IGV-dist")
    into createDistZip.baseName + "_${version}"

    doLast {
        project.exec { commandLine('chmod', '775', createDistZip.archivePath ) }
    }
}

task createLinuxDistZip(type: Zip, dependsOn: createDist) {
    baseName = "IGV_Linux"
    archiveName = createLinuxDistZip.baseName + "_${version}.zip"
    destinationDir = file("${buildDir}/distZip")
    if (!jdkBundleLinux.equals("")) {
        with copySpec { from jdkBundleLinux into "jdk-11" }
    }
    from ("${buildDir}/IGV-dist") {
        exclude "*.bat"
        exclude "*.command"
        exclude 'igvtools*'
        exclude 'lib/genomes'
    }
    into createLinuxDistZip.baseName + "_${version}"

    doLast {
        project.exec { commandLine('chmod', '775', createLinuxDistZip.archivePath) }
    }
}

task createMacDistZip(type: Zip, dependsOn: createDist) {
    baseName = "IGV_Mac"
    archiveName = createMacDistZip.baseName + "_${version}.zip"
    destinationDir = file("${buildDir}/distZip")
    if (!jdkBundleMac.equals("")) {
        with copySpec { from jdkBundleMac into "jdk-11" }
    }
    from ("${buildDir}/IGV-dist") {
        exclude "*.bat"
        exclude "*_hidpi*"
        exclude "igvtools*"
        exclude 'lib/genomes'
    }
    into createMacDistZip.baseName + "_${version}"

    doLast {
        project.exec { commandLine('chmod', '775', createMacDistZip.archivePath ) }
    }
}

task createMacAppDist(type: Copy, dependsOn: createDist) {
    if (!jdkBundleMac.equals("")) {
        with copySpec { from jdkBundleMac into "IGV_${version}.app/Contents/jdk-11" }
    }
    with copySpec {
        from ("scripts/mac.app") {
            exclude "Contents/Info.plist.template"
            exclude "Contents/MacOS/JavaAppLauncher"
        }
        into "IGV_${version}.app"
    }
    with copySpec {
        from ("scripts/java11/Info.plist.template")
        filter (ReplaceTokens, tokens: [ VERSION: version ])
        rename "Info.plist.template", "Info.plist"
        into "IGV_${version}.app/Contents"
    }
    with copySpec {
        from ("scripts/java11/IGV_mac.app.command")
        rename "IGV_mac.app.command", "IGV"
        into "IGV_${version}.app/Contents/MacOS"
    }
    with copySpec {
        from ("web/IGV_64.png")
        into "IGV_${version}.app/Contents/Resources"
    }
    with copySpec {
        from ("${buildDir}/IGV-dist/") include 'igv.args'
        into "IGV_${version}.app/Contents/Java/"
    }
    with copySpec {
        from ("${buildDir}/IGV-dist/lib") include '*.jar'
        into "IGV_${version}.app/Contents/Java/lib"
    }
    into "${buildDir}/IGV-MacApp-dist"

    doLast {
        project.exec { commandLine('chmod', '775', "${buildDir}/IGV-MacApp-dist/IGV_${version}.app" ) }
    }
}

task createMacAppDistZip(type: Zip, dependsOn: createMacAppDist) {
    archiveName = "IGV_${version}.app.zip"
    destinationDir = file("${buildDir}/distZip")
    from "${buildDir}/IGV-MacApp-dist"
    
    doLast {
        project.exec { commandLine('chmod', '775', createMacAppDistZip.archivePath ) }
    }
}

task createWinDist(type: Copy, dependsOn: createDist) {
    if (!jdkBundleWindows.equals("")) {
        with copySpec { from jdkBundleWindows into "IGV_${version}/jdk-11" }
    }
    with copySpec {
        from("${buildDir}/IGV-dist") {
            exclude "*.sh"
            exclude "*.command"
            exclude "igvtools*"
            exclude "igvtools_gui"
            exclude "igvtools_gui_hidpi"
            exclude 'lib/genomes'
        }
        from ("resources") { include "IGV_64.ico" }
        into "IGV_${version}"
    }
    with copySpec {
        // Create a build-specific NSIS installer script.
        from ("scripts/nsis/installer.nsi")
        filter (ReplaceTokens, tokens: [ VERSION: version ])
    }
    from ("scripts/nsis") { include "license_win.txt" }
    into "${buildDir}/IGV-WinExe-dist"
}

task createWinExeDist(type: Exec, dependsOn: createWinDist) {
    commandLine(makensisCommand, "-O${buildDir}/tmp/nsis-build.log",
                "${buildDir}/IGV-WinExe-dist/installer.nsi")
    doLast {
        if (makensisCommand.equals("")) {
            throw new GradleException("Required property not set: makensisCommand");
        }
    }
}
        
task signWinExeDist(type: Exec, dependsOn: createWinExeDist) {
    standardInput = new ByteArrayInputStream( keyPassword.getBytes() );
    commandLine(signcodeCommand, "-spc", spcFile, "-v", pvkFile, "-a", "sha1", 
                "-\$", "commercial", "-n", "IGV ${version}", "-i", "http://www.igv.org/",
                "-t", tsaurl, "-tr", "10", "${buildDir}/IGV-WinExe-dist/IGV_Win_${version}-installer.exe")
    doLast {
        if (signcodeCommand.equals("")) {
            throw new GradleException("Required property not set: signcodeCommand");
        }
    }
}

build.dependsOn createDistZip,createLinuxDistZip,createMacDistZip,createMacAppDistZip

if (!makensisCommand.equals("") && !signcodeCommand.equals("")) {
    build.dependsOn signWinExeDist
}