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