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.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()
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, ['.jiri_root', 'scripts', '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 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 jiriBin, '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
}

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