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

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