apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'jacoco'
apply plugin: 'maven'


// ====== CONFIGURATION ===== //
//isWindows = System.getProperty("os.name").toLowerCase().contains("windows")

ext {
    // For CI environment. Optional.
    jdk6BootClasspathEnv = System.getenv("JDK6_BOOT_CLASSPATH")
    pythonDir = "../py4j-python/"
    pythonDistDir = "${pythonDir}/dist"
    webDir = "../py4j-web/"
    pythonJavaDir = "${pythonDir}/py4j-java"
    pythonWebDir = "${pythonDir}/doc"
    pythonWebJavadocDir = "${pythonWebDir}/_static"
    isWindows = System.getProperty("os.name").toLowerCase().contains("windows")
}


// Only add spotless for JDK >= 1.8
if (JavaVersion.current().isJava8Compatible()) {
    apply plugin: 'com.diffplug.gradle.spotless'
    apply plugin: 'org.standardout.bnd-platform'
}

// FindBugs require JDK >= 1.7
if (JavaVersion.current().isJava7Compatible()) {
    apply plugin: 'findbugs'
}

if (JavaVersion.current().isJava8Compatible()) {
    platform {
        fetchSources = true

        eclipseHome = new File(eclipseHomePath)
        featureId = 'org.py4j.feature'
        featureName = 'Py4J Library'
        featureVersion = bundleVersion
        featureProvider = 'Py4J'
        categoryId = 'py4j'
        categoryName = 'Py4J'

        bundle file("build/libs/py4j-java-${version}.jar"), {
            bnd {
                symbolicName = 'py4j-java'
                bundleName = 'py4j-java'
                version = bundleVersion
                instruction 'DynamicImport-Package', '*'
                instruction 'Import-Package', '!javax.net'
                instruction 'Export-Package', 'py4j,py4j.commands,py4j.model,py4j.reflection'
                instruction 'Bundle-RequiredExecutionEnvironment', 'JavaSE-1.6'
                instruction 'Bundle-Description', 'Bridge between Python and Java - Java lib'
                instruction 'Bundle-DocURL', 'http://www.py4j.org'
                instruction 'Bundle-License', 'The New BSD License'
                addQualifier = true
            }
        }

        bundle file("build/libs/py4j-python-${version}.jar"), {
            bnd {
                symbolicName = 'py4j-python'
                bundleName = 'py4j-python'
                version = bundleVersion
                instruction 'DynamicImport-Package', '*'
                instruction 'Bundle-RequiredExecutionEnvironment', 'JavaSE-1.6'
                instruction 'Bundle-Description', 'Bridge between Python and Java - Python lib'
                instruction 'Bundle-DocURL', 'http://www.py4j.org'
                instruction 'Eclipse-BundleShape', 'dir'
                instruction 'Bundle-License', 'The New BSD License'
                instruction 'Export-Package', ''
                addQualifier = true
            }
        }
    }
}

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // Only add spotless for JDK >= 1.8
        if (JavaVersion.current().isJava8Compatible()) {
            classpath group: 'com.diffplug.gradle.spotless', name: 'spotless', version: '1.3.2'
            classpath 'org.standardout:bnd-platform:1.3.0'
        }
    }
}

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.13.2'
    // For Java 8 Support
    if (JavaVersion.current().isJava7Compatible()) {
        findbugs group: 'com.google.code.findbugs', name: 'findbugs', version: '3.0.+'
    }
}

// Only add spotless for JDK >= 1.8
if (JavaVersion.current().isJava8Compatible()) {
    spotless {
        java {
            licenseHeaderFile 'py4j.license.java'
            eclipseFormatFile 'py4j.formatter.xml'
            importOrderFile 'py4j.importorder'
        }
    }
}

// Use environment variable only if the property is not set
if (jdk6BootClasspathEnv && !jdk6BootClasspath) {
    jdk6BootClasspath = jdk6BootClasspathEnv
}

if (jdk6BootClasspath) {
    tasks.withType(JavaCompile) {
        options.bootClasspath = "$jdk6BootClasspath"
    }
}

tasks.withType(JavaCompile) {
    sourceCompatibility = "1.6"
    targetCompatibility = "1.6"
    options.fork = true
    options.encoding = "UTF-8"
}

jacoco {
    // For Java 8 Support
    toolVersion = "0.7.6.201602180812"
}

jacocoTestReport {
    reports {
        xml.enabled true
        csv.enabled false
        html.enabled true
    }
}

// ====== CUSTOM TASKS ====== //

// Maven support
task createPom {
    description 'Creates Py4J maven build file.'
    doLast {
        pom {
            project {
                parent {
                    groupId 'org.sonatype.oss'
                    artifactId 'oss-parent'
                    version '7'
                }
                packaging 'jar'
                groupId 'net.sf.py4j'
                artifactId 'py4j'
                version '0.10.9.4'
                name 'Py4J'
                description 'Py4J enables Python programs running in a Python interpreter to dynamically access Java objects in a Java Virtual Machine. Methods are called as if the Java objects resided in the Python interpreter and Java collections can be accessed through standard Python collection methods. Py4J also enables Java programs to call back Python objects.'
                scm {
                    connection 'scm:git:git@github.com:bartdag/py4j.git'
                    developerConnection 'scm:git:git@github.com:bartdag/py4j.git'
                    url 'git@github.com:bartdag/py4j.git'
                }
                developers {
                    developer {
                        id 'bartdag'
                        name 'Barthelemy Dagenais'
                        url 'http://infobart.com/'
                    }
                }
                licenses {
                    license {
                        name 'The New BSD License'
                        url 'http://www.opensource.org/licenses/bsd-license.html'
                    }
                }
                properties {
                    'project.build.sourceEncoding' 'UTF-8'
                    'project.build.outputEncoding' 'UTF-8'
                }
            }
        }.withXml {
            asNode().appendNode('build').appendNode('plugins').appendNode('plugin').with {
                appendNode('groupId', 'org.apache.maven.plugins')
                appendNode('artifactId', 'maven-compiler-plugin')
                appendNode('version', '3.3')
                appendNode('configuration').with {
                    appendNode('source', '1.6')
                    appendNode('target', '1.6')
                }
            }
        }.writeTo("pom.xml")
    }
}

// If someone wants to access all examples
task testsJar(type: Jar) {
    description 'Creates a jar file with all test classes.'
    baseName = 'py4j-tests'
    from sourceSets.test.output
    from sourceSets.main.output
}

task sourcesJar(type: Jar, dependsOn: classes) {
    description 'Creates a sources jar.'
    classifier = 'sources'
    from sourceSets.main.allSource
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    description 'Creates a jar with javadoc.'
    classifier = 'javadoc'
    from javadoc.destinationDir
}

task pythonSourcesJar(type: Jar) {
    description 'Creates a python src jar.'
    baseName = 'py4j-python'
    from pythonDir
    include 'src/py4j/**/*.py'
    include 'LICENSE.txt'
    exclude '**/__pycache__/**'
}

// We cannot use Copy because we are copying into the main directory
// And Windows does not like that:
// https://discuss.gradle.org/t/error-with-a-copy-task-on-windows/1803
task copyMainJar(type: Exec, dependsOn: jar) {
    description 'Copies and rename Py4J main jar for backward compatibility.'
    workingDir '.'
    if (isWindows) {
        commandLine 'cmd', '/c', 'copy', '/Y'
        ext.baseLibPath = 'build\\libs\\'
    } else {
        commandLine 'cp', '-f' 
        ext.baseLibPath = 'build/libs/'
    }
    args "${baseLibPath}py4j-java-${version}.jar", "py4j${version}.jar"
}

// Make Py4J.org website and doc
task buildWeb(type: Exec) {
    description 'Builds Py4J static web site and documentation.'
    workingDir webDir
    if (isWindows) {
        commandLine 'cmd', '/c', 'make.bat'
    } else {
        executable 'make'
    }
    args 'html'
}

task copyWebPython(type: Copy, dependsOn: 'buildWeb') {
    description 'Copies Py4J static web site to py4j-python directory.'
    from("${webDir}/_build/html")
    into pythonWebDir
}

task copyWebJavadocPython(type: Copy, dependsOn: ['javadoc', 'copyWebPython']) {
    description 'Copies javadoc into Py4J static web site static directory.'
    from "${buildDir}/docs"
    into pythonWebJavadocDir
}

// Copy Java build to Python build for Python Source Build
task copyJavaPython(type: Copy, dependsOn: ['copyMainJar', 'javadoc', 'createPom']) {
    description 'Copies py4j-java source and build files to py4j-python directory.'
    from(projectDir) {
        include "src"
        include "ant.properties"
        include "build.xml"
        include "gradle.properties"
        include "build.gradle"
        include "pom.xml"
        include "LICENSE.txt"
    }
    from "py4j${version}.jar"
    from "${buildDir}/docs"
    into pythonJavaDir
}

// Python Source Dist
task buildPythonSrc(type: Exec, dependsOn: ['copyWebJavadocPython', 'copyJavaPython']) {
    description 'Builds python source distribution.'
    workingDir pythonDir;
    executable 'python'
    args 'setup.py', 'sdist', '--formats=zip,gztar'
}

// Python Wheel Dist
task buildPythonWheel(type: Exec, dependsOn: ['copyJavaPython']) {
    description 'Builds python wheel (binary) distribution.'
    workingDir pythonDir;
    executable 'python'
    args 'setup.py', 'bdist_wheel'
}

// Python Global Dist
task buildPython(dependsOn: ['buildPythonSrc', 'buildPythonWheel']) {
    description 'Builds python distributions (source and wheel).'

}

// Clean Py4J backward compatibility jar
task cleanMainJar(type: Delete) {
    delete "./py4j${version}.jar"
}

// Clean web dist
task cleanWeb(type: Exec) {
    workingDir webDir
    if (isWindows) {
        commandLine 'cmd', '/c', 'make.bat'
    } else {
        executable 'make'
    }
    args 'clean'
}

// Clean python java dir
task cleanPythonWeb(type: Delete) {
    delete pythonWebDir
}

// Clean python java dir
task cleanPythonJava(type: Delete) {
    delete pythonJavaDir
}

// Clean python dist
task cleanPython(type: Delete) {
    delete "${pythonDir}/build"
    delete "${pythonDir}/dist"
}


// ====== TASK DEPENDENCIES AND DISABLING ===== //

// For now, tests are not clean and that's fine because we want to test many
// unclean scenarios.
if (JavaVersion.current().isJava7Compatible()) {
    findbugsTest.enabled = false
}

// Build all jars
artifacts {
    archives sourcesJar
    archives testsJar
    archives javadocJar
    archives pythonSourcesJar
}

assemble {
    dependsOn copyMainJar
}

if (JavaVersion.current().isJava8Compatible()) {
    bundles {
        dependsOn assemble
    }
}

clean {
    dependsOn cleanMainJar
    dependsOn cleanPython
    dependsOn cleanWeb
    dependsOn cleanPythonJava
    dependsOn cleanPythonWeb
}
