buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
        classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
    }
}

apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply plugin: 'wrapper'

android {
    buildToolsVersion '22.0.1'
    compileSdkVersion 22

    defaultConfig {
        minSdkVersion 19
    }

    lintOptions {
        abortOnError false
    }

    defaultConfig {
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
}

repositories {
    mavenCentral()
}

dependencies {
    compile project(':lib')
    androidTestCompile 'junit:junit:4.12'
    androidTestCompile 'com.google.truth:truth:0.25'
    // This dependency exists only to work around an issue in the sdkmanager plugin v0.12.0. This
    // should be fixed when http://git.io/vIXec is checked in and a release is made.
    androidTestCompile 'com.android.support:support-v4:21.0.0'
    androidTestCompile('com.android.support.test:runner:0.3') {
        exclude group: 'junit'  // junit:junit-dep conflicts with junit:unit
    }
}

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 getArch() {
    return System.properties['os.arch'].toLowerCase()
}

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

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

class VanadiumEnvironment {
    File jiriRoot;
    File jiriBin;
    File thirdPartyGoBinDir;

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

        result.thirdPartyGoBinDir = new File(result.jiriRoot,
                ['third_party', 'android', 'go', 'bin'].join(File.separator))
        def thirdPartyGoBin = new File(result.thirdPartyGoBinDir, 'go')
        if (!thirdPartyGoBin.exists() || !thirdPartyGoBin.isFile() || !thirdPartyGoBin.canExecute()) {
            throw new InvalidUserDataException(
                    thirdPartyGoBin.toString() + " does not exist or is not an executable file. "
                    + "You probably didn't install the android profile. Try running\n\n"
                    + "jiri profile install android\n\nand then try building again.")
        }

        def syncbaseOutputDir = new File(result.jiriRoot,
                ['third_party', 'cout', 'android_arm', 'leveldb'].join(File.separator))
        if (!syncbaseOutputDir.exists() || !syncbaseOutputDir.isDirectory()) {
            throw new InvalidUserDataException(
                    syncbaseOutputDir.toString() + " does not exist or is not a directory. "
                    + "You probably didn't install the android syncbase profile. Try running\n\n"
                    + "GOOS=android GOARCH=arm jiri profile install syncbase"
                    + "\n\nand then try building again"
            )
        }

        return result
    }
}

task checkVanadiumEnvironment {
    VanadiumEnvironment.getVanadiumEnvironment()
    if (!isAmd64()) {
        throw new InvalidUserDataException("Android Vanadium builds only enabled on amd64 "
                + "architectures, not: " + getArch())
    }
    if (!isLinux() && !isDarwin()) {
        throw new InvalidUserDataException("Android Vanadium builds only enabled on "
                + "linux/darwin systems, not: " + getOS())
    }
}

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

    environment 'JIRI_PROFILE': 'android'
    environment 'PATH': [env.thirdPartyGoBinDir.getAbsolutePath(), existingPath].join(File.pathSeparator)

    commandLine env.jiriBin.getAbsolutePath(), 'go', 'install',
            '-buildmode=c-shared', '-v', '-tags', 'android', 'v.io/x/jni/main'
}

// Copy the shared library to its ultimate destination.
task copyVanadiumLib(type: Copy, dependsOn: goBuildVanadiumLib) {
    from jiriRoot + '/release/go/pkg/android_arm/v.io/x/jni'
    into 'src/main/jniLibs/armeabi-v7a'
    include 'main.a'
    rename 'main.a', 'libv23.so'
}

clean {
    delete 'src/main/jniLibs/armeabi-v7a/libv23.so'
}

task sourceJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier "source"
}

publishing {
    publications {
        androidLibrary(MavenPublication) {
            groupId 'io.v'
            artifactId 'vanadium-android'
            version '0.1-SNAPSHOT'
            artifact(sourceJar)
            artifact("$buildDir/outputs/aar/android-lib-release.aar")
        }
    }
    repositories {
        maven {
            credentials {
                username 'admin'
                password 'admin123'
            }
            url "http://srdjan.mtv:8081/nexus/content/repositories/test_repo"
        }
    }
}

wrapper {
    gradleVersion = '2.4'
}

tasks.'preBuild'.dependsOn(copyVanadiumLib)
tasks.'publish'.dependsOn(tasks.'assemble')
