import groovy.json.internal.Charsets

buildscript {
    repositories {
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
        classpath 'io.v:gradle-plugin:1.4'
    }
}

apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'io.v.vdl'
apply plugin: 'com.jfrog.bintray'

sourceCompatibility = 1.7
targetCompatibility = 1.7

// You should change this after releasing a new version of the library. See the
// list of published versions at https://repo1.maven.org/maven2/io/v/vanadium.
def releaseVersion = '1.5'

dependencies {
    compile group: 'joda-time', name: 'joda-time', version: '2.7'
    compile group: 'com.google.guava', name: 'guava', version: '18.0'
    compile group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.1'
    testCompile group: 'junit', name: 'junit', version: '4.12'
    testCompile group: 'com.google.truth', name: 'truth', version: '0.25'
    testCompile 'org.reflections:reflections:0.9.9-RC1'
}

repositories {
    mavenCentral()
    jcenter()
}

clean {
    delete 'generated-src'
}

public static isDarwin() {
    return getOS().contains("os x")
}

public static isLinux() {
    return getOS().contains("linux")
}

public static isAmd64() {
    return getArch().contains("x86_64") || getArch().contains("amd64")
}

public static isArm() {
    return getArch().contains("arm")
}

public static getArch() {
    return System.properties['os.arch'].toLowerCase()
}

public static getOS() {
    return System.properties['os.name'].toLowerCase()
}

def String getOsName() {
    if (isLinux()) {
        return "linux";
    } else if (isDarwin()) {
        return "macosx";
    } else {
        throw new IllegalStateException("Unsupported operating system " + System.properties.'os.name')
    }
}

public static newStyleProfiles() {
    return new File(System.getenv()['JIRI_ROOT'], '.jiri_v23_profiles').exists()
}

def jiriRoot = VanadiumEnvironment.getVanadiumEnvironment().jiriRoot.getAbsolutePath()
def jiriBin = VanadiumEnvironment.getVanadiumEnvironment().jiriBin.getAbsolutePath()

sourceSets.main.java.srcDirs += 'generated-src/vdl'

class VanadiumEnvironment {
    File jiriRoot;
    File jiriBin;

    public static getVanadiumEnvironment() {
        VanadiumEnvironment result = new VanadiumEnvironment()

        if (!System.getenv().containsKey('JIRI_ROOT')) {
            throw new InvalidUserDataException("JIRI_ROOT is not set. "
                    + "Please follow the Vanadium installation instructions at "
                    + "https://github.com/vanadium/docs/blob/master/installation.md")
        }

        result.jiriRoot = new File(System.getenv()['JIRI_ROOT'])
        result.jiriBin = new File(result.jiriRoot, ['devtools', 'bin', 'jiri'].join(File.separator))
        if (!result.jiriBin.exists() || !result.jiriBin.isFile() || !result.jiriBin.canExecute()) {
            throw new InvalidUserDataException(
                    result.jiriBin.toString() + " does not exist or is not an executable file. "
                    + "Please follow the Vanadium installation instructions at "
                    + "https://github.com/vanadium/docs/blob/master/installation.md")
        }
        return result
    }
}

task checkVanadiumEnvironment {
    VanadiumEnvironment.getVanadiumEnvironment()

    if (System.getenv('JAVA_HOME') == null) {
        throw new InvalidUserDataException("The JAVA_HOME environment variable is not set. "
                + "Please set it to the root of a JDK installation directory.  If JDK isn't "
                + "installed, you probably didn't install the java profile: try running\n\n"
                + "jiri v23-profile install java\n\nand then try building again.")
    }
    if (!isAmd64() && !isArm()) {
        throw new InvalidUserDataException("Java Vanadium builds only enabled on amd64 "
                + "and arm architectures, not: " + getArch())
    }
    if (!isLinux() && !isDarwin()) {
        throw new InvalidUserDataException("Java Vanadium builds only enabled on "
                + "linux/darwin systems, not: " + getOS())
    }
}

task goBuildVanadiumLib(type: Exec, dependsOn: checkVanadiumEnvironment) {
    def existingPath = System.getenv('PATH')
    if (existingPath == null) {
        existingPath = ""
    }

    // NOTE(spetrovic): we add the '-installsuffix=shared' flag because the build doesn't work
    // without it on linux/arm.  (There is some conflict with "regular", i.e., non-shared builds).
    if (newStyleProfiles()) {
        commandLine jiriBin, 'go', '--profiles=java', 'install', '-buildmode=c-shared', '-v',
                '-tags', 'java', '-installsuffix=shared', 'v.io/x/jni/main'
    } else {
        environment 'JIRI_PROFILE': 'java'
        commandLine jiriBin, 'go', 'install', '-buildmode=c-shared', '-v', '-tags', 'java',
                '-installsuffix=shared', 'v.io/x/jni/main'
    }
}

// Copy the shared library to its ultimate destination.
if (isLinux()) {
    def installDir = ''
    if (isAmd64()) {
        installDir = '/release/go/pkg/linux_amd64_shared_shared/v.io/x/jni'
    } else {  // arm
        installDir = '/release/go/pkg/linux_arm_shared/v.io/x/jni'
    }
    task copyVanadiumLib(type: Copy, dependsOn: goBuildVanadiumLib) {
        from jiriRoot + installDir
        into 'build/libs'
        include 'main.a'
        rename 'main.a', 'libv23.so'
    }
} else {  // darwin
    task copyVanadiumLib(type: Copy, dependsOn: goBuildVanadiumLib) {
        from jiriRoot + '/release/go/pkg/darwin_amd64_shared/v.io/x/jni'
        into 'build/libs'
        include 'main.a'
        rename 'main.a', 'libv23.dylib'
    }
}

// Add shared library dependency to our tests.
tasks.withType(Test) {
    if (isDarwin()) {
        // TODO(sjr): remove these when
        // https://github.com/vanadium/issues/issues/567 is resolved.
        jvmArgs '-XX:+UnlockDiagnosticVMOptions'
        jvmArgs '-XX:-LogEvents'
    }
    systemProperty "java.library.path", "build/libs"
}

tasks.'processTestResources'.dependsOn(copyVanadiumLib)

// We cannot reliably determine whether the native vanadium lib is up-to-date.
// Therefore we always run the tests even if Gradle thinks that there is no
// need.
tasks.'test'.outputs.upToDateWhen({ false })

tasks.'test' << {
    io.v.VanadiumTestXmlAggregator.mergeAllTestXmlFiles(new File("${buildDir}/test-results"), new File("${buildDir}/aggregated-test-results.xml"))
}

task buildVanadiumLib(dependsOn: copyVanadiumLib) {}

task sourceJar(type: Jar) {
    baseName 'sources'

    from sourceSets.main.allJava
}

javadoc {
    if (JavaVersion.current().isJava8Compatible()) {
        options.addStringOption('Xdoclint:none', '-quiet')
    }
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    baseName 'javadoc'

    from javadoc.destinationDir
}

task natives(type: Jar, dependsOn: buildVanadiumLib) {
    baseName 'natives'

    if (isLinux()) {
        from 'build/libs/libv23.so'
    } else if (isDarwin()) {
        from 'build/libs/libv23.dylib'
    } else {
        throw new InvalidUserDataException("unsupported operating system: " + getOS())
    }
}

task emptyJar(type: Jar) {
    baseName 'empty'

    project.buildDir.mkdirs()
    File explanation = new File(project.buildDir, 'empty-jar.txt')
    explanation.setText('This artifact has no Java sources or javadoc', Charsets.US_ASCII.name())
    from explanation
}

def pomDependencyText = """
<dependencies>
    <dependency>
        <groupId>io.v</groupId>
        <artifactId>vanadium-without-natives</artifactId>
        <version>${releaseVersion}</version>
    </dependency>
    <dependency>
        <groupId>io.v</groupId>
        <artifactId>vanadium-natives-linux</artifactId>
        <version>${releaseVersion}</version>
    </dependency>
    <dependency>
        <groupId>io.v</groupId>
        <artifactId>vanadium-natives-macosx</artifactId>
        <version>${releaseVersion}</version>
    </dependency>
</dependencies>
"""

def pomDependencies = new XmlParser().parseText(pomDependencyText)

// Adds XML nodes representing fields required for publication to Maven central to the given node.
def addMavenCentralMetadata(Node node) {
    node.appendNode('name', 'Vanadium Java library')
    node.appendNode('description',
            'Java libraries for writing Vanadium applications')
    node.appendNode('url', 'https://github.com/vanadium/java')

    def license = node.appendNode('licenses').appendNode('license')
    license.appendNode('name', 'New BSD License')
    license.appendNode('url', 'https://github.com/vanadium/java/blob/master/LICENSE')
    license.appendNode('distribution', 'repo')

    node.appendNode('scm').appendNode('url',
            'https://github.com/vanadium/java.git')

    def developerInfo = node.appendNode('developers').appendNode('developer')
    developerInfo.appendNode('id', 'vanadium')
    developerInfo.appendNode('name', 'The Vanadium Contributors')
    developerInfo.appendNode('email', 'vanadium-discuss@v.io')
}

publishing {
    publications {
        mavenNoNatives(MavenPublication) {
            groupId 'io.v'
            artifactId 'vanadium-without-natives'
            version releaseVersion

            from components.java

            artifact sourceJar {
                classifier "sources"
            }

            artifact javadocJar {
                classifier "javadoc"
            }

            pom.withXml {
                addMavenCentralMetadata(asNode())
            }
        }

        mavenJava(MavenPublication) {
            groupId 'io.v'
            artifactId 'vanadium'
            version releaseVersion

            from components.java

            // No archives in this one, it's a meta package only.
            artifacts.clear()

            // Maven Central does require source and javadoc jars
            artifact source: emptyJar, classifier: 'sources'
            artifact source: emptyJar, classifier: 'javadoc'

            pom.withXml {
                for (Node node : pomDependencies.children()) {
                    asNode().dependencies[0].append(node)
                }
                addMavenCentralMetadata(asNode())
            }
        }

        mavenNatives(MavenPublication) {
            groupId 'io.v'
            artifactId 'vanadium-natives-' + getOsName()
            version releaseVersion

            // Maven Central does require source and javadoc jars
            artifact source: emptyJar, classifier: 'sources'
            artifact source: emptyJar, classifier: 'javadoc'

            artifact natives

            pom.withXml {
                addMavenCentralMetadata(asNode())
            }
        }
    }
}

vdl {
    inputPaths += [jiriRoot, 'release', 'go', 'src'].join(File.separator)
    vdlRootPath = [jiriRoot, 'release', 'go', 'src', 'v.io', 'v23', 'vdlroot'].join(File.separator)
    generateVdlRoot = true
}

bintray {
    user = project.properties.bintrayUsername
    key = project.properties.bintrayApiKey
    pkg {
        desc = 'Java libraries for writing Vanadium applications'
        websiteUrl = 'https://github.com/vanadium/java'
        repo = 'io.v'
        name = 'vanadium'
        licenses = ['BSD New']
        vcsUrl = 'https://github.com/vanadium/java.git'
        version {
            name = releaseVersion
            gpg {
                sign = true
            }
        }
        userOrg = 'vanadium'
    }
    publications = ['mavenJava', 'mavenNoNatives', 'mavenNatives']
}

checkstyle {
    configFile = file('checkstyle_config.xml')
    configProperties.put('checkstyle_ignore_path', file('checkstyle_ignore.xml').getAbsolutePath())
}

findbugs {
    toolVersion = "3.0.1"
    excludeFilter = file('findbugs/findbugs_filter.xml')
}

tasks.withType(FindBugs) { findbugsTask ->
    reports {
        xml {
            withMessages = true
        }
    }

    // For each findbugs task, add a task to dump the findbugs report in plain
    // text. For this, we translate the findbugs report XML to text using a
    // custom XSLT template.
    def reportTask = task "${findbugsTask.name}-report" << {
        ant.xslt(in: findbugsTask.reports.xml.destination,
                 out: findbugsTask.reports.xml.destination.path + '.txt',
                 style: 'findbugs/findbugs_report.xsl')
        println file(findbugsTask.reports.xml.destination.path + '.txt').text
    }

    // run the report task even if the findbugs check failed
    findbugsTask.finalizedBy(reportTask)
    tasks.check.dependsOn(reportTask)
}
