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.6'
    }
}

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.11'

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

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

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

class VanadiumEnvironment {
    File jiriRoot;

    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://vanadium.github.io/installation/")
        }

        result.jiriRoot = new File(System.getenv()['JIRI_ROOT'])
        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 profile install v23: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).
    commandLine 'jiri', 'go', '--profiles=v23:java', '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
    vdlToolPath = 'vdl'
}

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