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

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