buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath (
                'com.android.tools.build:gradle:2.1.0',
                'com.github.dcendents:android-maven-gradle-plugin:1.3',
                'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'
        )
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

// You should update this after releasing a new version of the Syncbase API. See the
// list of published versions at: https://repo1.maven.org/maven2/io/v/syncbase
version = '0.1.5'
group = 'io.v'

def siteUrl = 'https://github.com/vanadium/java/syncbase'
def gitUrl = 'https://github.com/vanadium/java.git'
def pkgDesc = 'Offline-capable storage system with secure peer-to-peer data synchronization'

apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'

archivesBaseName = 'syncbase'

install {
    repositories.mavenInstaller {
        pom {
            project {
                packaging 'aar'

                name 'Syncbase'
                description pkgDesc
                url siteUrl

                licenses {
                    license {
                        name 'New BSD License'
                        url 'https://github.com/vanadium/java/blob/master/LICENSE'
                        distribution 'repo'
                    }
                }
                scm {
                    connection gitUrl
                    url siteUrl
                }
                developers {
                    developer {
                        id 'vanadium'
                        name 'The Vanadium Contributors'
                        email 'vanadium-discuss@v.io'
                    }
                }
            }
        }
    }
}

tasks.bintrayUpload.dependsOn(tasks.install)

bintray {
    // These properties can be obtained after obtaining a bintray account and should be specified in
    // $HOME/.gradle/gradle.properties. See the instructions in RELEASING.md to set this up.
    user = project.properties.bintrayUsername
    key = project.properties.bintrayApiKey

    configurations = ['archives']

    pkg {
        desc = pkgDesc
        websiteUrl = siteUrl
        vcsUrl = gitUrl
        repo = group
        name = archivesBaseName
        licenses = ['BSD New']
        userOrg = 'vanadium'
        publish = true

        version {
            name = project.version
            gpg {
                sign = true
            }
        }
    }
}

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 23
        multiDexEnabled true
        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    lintOptions {
        abortOnError false
    }

    testOptions {
        unitTests.all {
            systemProperty 'java.library.path', 'build/libs'
        }
        // http://tools.android.com/tech-docs/unit-testing-support#TOC-Method-...-not-mocked.-
        // TODO(sadovsky): Seems dangerous to set this. We should probably mock out the relevant
        // Android methods, e.g. android.util.Log.
        unitTests.returnDefaultValues = true
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'io.v:vanadium-android:2.1.7'
    testCompile 'com.google.truth:truth:0.28'
    testCompile 'junit:junit:4.12'
    // We need to overwrite org.json because it's mocked by default. For some reason setting
    // the unitTests.returnDefaultValues doesn't help in this case.
    testCompile 'org.json:org.json:2.0'
    androidTestCompile 'com.android.support.test:runner:0.4.1'
    androidTestCompile 'com.android.support.test:rules:0.4.1'
}

task clean(type: Delete) {
    delete rootProject.buildDir
    delete 'src/main/jniLibs/'
    delete 'build/libs/'
}

class VanadiumEnvironment {
    File jiriRoot;

    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'))
        return result
    }
}

def addSyncbaseLib(Map args) {
    def nameSuffix = args.nameSuffix
    def profile = args.profile
    def tags = args.tags
    def srcDir = args.srcDir
    def targetDir = args.targetDir
    def targetArg = (args.target != null) ? "--target=${args.target}" : ''
    def libName = args.libName
    def jiriRoot = ''
    try {
        jiriRoot = VanadiumEnvironment.getVanadiumEnvironment().jiriRoot.getAbsolutePath()
    } catch (InvalidUserDataException e) {
        return
    }

    def check = task("checkVanadiumEnvironment-${nameSuffix}", type: Exec) {
        if (targetArg != '') {
            commandLine 'jiri', 'profile', 'list', targetArg, profile
        } else {
            commandLine 'jiri', 'profile', 'list', profile
        }
        standardOutput = new ByteArrayOutputStream()
        doLast {
            if (standardOutput.toString() == '') {
                throw new InvalidUserDataException(
                        "A necessary profile/target is missing. Try running\n\n"
                        + "  jiri profile install ${targetArg} ${profile}\n\n"
                        + "and then building again."
                )
            }
        }
    }

    def goBuild = task("buildSyncbaseLib-${nameSuffix}", type: Exec, dependsOn: check) {
        if (targetArg != '') {
            commandLine 'jiri', 'go', targetArg, 'install', '-buildmode=c-shared', '-v', '-tags',
                    tags, 'v.io/x/ref/services/syncbase/bridge/cgo'
        } else {
            commandLine 'jiri', 'go', "--profiles=${profile}", 'install', '-buildmode=c-shared',
                    '-v', '-tags', tags, 'v.io/x/ref/services/syncbase/bridge/cgo'
        }
    }

    // Copy the shared library to its ultimate destination.
    def copyLib = task("copySyncbaseLib-${nameSuffix}", type: Copy, dependsOn: goBuild) {
        from "${jiriRoot}/release/go/pkg/${srcDir}/v.io/x/ref/services/syncbase/bridge"
        into targetDir
        rename 'cgo.a', libName
    }

    tasks.copySyncbaseLib.dependsOn(copyLib)
}

task(copySyncbaseLib)
addSyncbaseLib nameSuffix: 'android-amd64', target: 'amd64-android', profile: 'v23:android',
        tags: 'android', srcDir: 'android_amd64_shared', targetDir: 'src/main/jniLibs/x86_64',
        libName: 'libsyncbase.so'
addSyncbaseLib nameSuffix: 'android-arm', target: 'arm-android', profile: 'v23:android',
        tags: 'android', srcDir: 'android_arm_shared', targetDir: 'src/main/jniLibs/armeabi-v7a',
        libName: 'libsyncbase.so'
def os = System.properties['os.name'].toLowerCase()
def arch = System.properties['os.arch'].toLowerCase()
if (arch.contains('x86_64') || arch.contains('amd64')) {
    if (os.contains('linux')) {
        addSyncbaseLib nameSuffix: 'native', profile: 'v23:java', tags: 'java',
                srcDir: 'linux_amd64_shared', targetDir: 'build/libs', libName: 'libsyncbase.so'
    } else if (os.contains('os x')) {
        addSyncbaseLib nameSuffix: 'native', profile: 'v23:java', tags: 'java',
                srcDir: 'darwin_amd64', targetDir: 'build/libs', libName: 'libsyncbase.dylib'
    }
}
tasks.preBuild.dependsOn(copySyncbaseLib)
