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 '21.1.2'
    compileSdkVersion 19

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

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

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 (!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 checkVanadiumSyncbaseEnvironment(type: Exec, dependsOn: checkVanadiumEnvironment) {
    if (newStyleProfiles()) {
        commandLine jiriBin, 'v23-profile', 'env',
            '-profile=syncbase', '--target=arm-android', 'V23_TARGET_INSTALLATION_DIR='
    } else {
        commandLine "echo", [jiriRoot, 'third_party', 'cout', 'android_arm', 'leveldb'].join(File.separator)
    }
    standardOutput = new ByteArrayOutputStream()
    doLast {
        def syncbaseOutputDir = new File(standardOutput.toString().trim())
        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 base profile. Try    running\n\n"
                + "jiri v23-profile install --target=android=arm-android base"
                + "\n\nand then try building again"
            )
        }
    }
}

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

    // NOTE(spetrovic): we add the '-installsuffix=shared' flag as a safe measure, because the build
    // without it doesn't work on linux/arm.  (It does work on android/arm, but we are playing it
    // safe here.)
    if (newStyleProfiles()) {
        environment 'GOOS': 'android'
        environment 'GOARCH': 'arm'
        commandLine jiriBin, 'go', '--target=android', 'install',
                '-buildmode=c-shared', '-v', '-tags', 'android',
                '-installsuffix=shared', 'v.io/x/jni/main'
    } else {
        environment 'JIRI_PROFILE': 'android'
        commandLine jiriBin, 'go', 'install',
            '-buildmode=c-shared', '-v', '-tags', 'android',
                '-installsuffix=shared', '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_shared/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"
}

def pomDependencyText = '''
<dependencies>
    <dependency>
        <groupId>io.v</groupId>
        <artifactId>vanadium-without-natives</artifactId>
        <version>0.1-SNAPSHOT</version>
    </dependency>
</dependencies>
'''

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

publishing {
    publications {
        androidLibrary(MavenPublication) {
            groupId 'io.v'
            artifactId 'vanadium-android'
            version '0.1-SNAPSHOT'
            artifact(sourceJar)
            artifact("$buildDir/outputs/aar/android-lib-release.aar")

            pom.withXml {
                asNode().append(pomDependencies)
            }
        }
    }
    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')
