import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.3"

    defaultConfig {
        applicationId "net.named_data.nfd"
        minSdkVersion 23
        targetSdkVersion 23
        versionCode 4006
        versionName "0.3.0 (NFD 0.6.0, ndn-cxx 0.6.0)"
        multiDexEnabled true
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            debuggable true
            jniDebuggable true
        }
    }
    sourceSets {
        main {
            java.srcDirs "src/main/java"
            res.srcDirs "src/main/res"
            jniLibs.srcDir 'src/main/libs'
            jni.srcDirs = [] //disable automatic ndk-build call
        }
        androidTest.setRoot('tests')
        androidTest.java.srcDirs = ['tests/src']
    }
    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
    lintOptions {
      abortOnError false
    }

    splits {
        abi {
            enable true // enable ABI split feature to create one APK per ABI
            universalApk false // don't generate an additional APK that targets all the ABIs
        }
    }

    // map for the version code
    // versionCode digit for each supported ABI, with 64bit>32bit and x86>armeabi-*
    project.ext.versionCodes = [//'armeabi': 1, // Deprecated in r16. Will be removed in r17. No hard float.
                                'armeabi-v7a': 2,
                                'arm64-v8a': 3,
                                // 'mips': 5,   // Deprecated in r16. Will be removed in r17. Uses hard-float, and assumes a CPU:FPU clock ratio of 2:1 for maximum compatibility. Provides neither micromips nor MIPS16.
                                // 'mips64': 6, // Deprecated in r16. WIll be removed in r17
                                'x86': 8,
                                'x86_64': 9]

    android.applicationVariants.all { variant ->
        // assign different version code for each output
        variant.outputs.each { output ->
            output.versionCodeOverride = project.ext.versionCodes.get(
                    output.getFilter(
                            com.android.build.OutputFile.ABI), 0) * 1000000 +
                    defaultConfig.versionCode
        }
    }

    task copyNdnCxxHeaders(type: Copy) {
        from('src/main/jni/ndn-cxx/src') {
            include '**/*.hpp'
        }
        into 'build/generated/source/include/ndn-cxx'
    }

    // call regular ndk-build(.cmd) script from app directory
    task ndkBuild(type: Exec) {
        dependsOn copyNdnCxxHeaders
        def args = [getNdkBuildCmd(), '-C', file('src/main').absolutePath]

        if (System.env.NDK_BUILD_PARALLEL != null) {
           args.add("-j" + System.env.NDK_BUILD_PARALLEL)
        }
        else {
           args.add("-j" + Runtime.runtime.availableProcessors())
        }

        if (System.env.NDK_BUILD_ABI != null) {
           args.add("APP_ABI=" + System.env.NDK_BUILD_ABI)
        }

        if (System.env.NDK_DEBUG != null) {
           args.add("V=1")
        }
        commandLine args
    }

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn ndkBuild
    }

    task cleanNative(type: Exec) {
        commandLine getNdkBuildCmd(), '-C', file('src/main').absolutePath, 'clean'
    }

    clean.dependsOn cleanNative
}

def getNdkBuildCmd() {
    def ndk_build = getNdkDir() + "/ndk-build"
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        ndk_build += ".cmd"
    }

    return ndk_build
}


def getNdkDir() {
    if (System.env.ANDROID_NDK_ROOT != null)
        return System.env.ANDROID_NDK_ROOT

    Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())

    def ndk_dir = properties.getProperty('ndk.dir', null)
    if (ndk_dir == null) {
        throw new GradleException("NDK location not found. Define location with ndk.dir in the local.properties file or with an ANDROID_NDK_ROOT environment variable.")
    }
    return ndk_dir
}

repositories {
    mavenLocal()
    mavenCentral()
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots/"
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:support-v4:26.1.0'
    implementation 'com.android.volley:volley:1.0.0'

    implementation('com.intel.jndn.management:jndn-management:1.1.3') {
      exclude group: 'net.named-data', module: 'jndn'
    }
    implementation('net.named-data:jndn-android:0.15') {
      exclude group: 'org.xerial'
      exclude group: 'com.google.android'
    }
    implementation 'net.named-data.jndn-xx:jndn-xx-util:0.0.1'
    implementation 'joda-time:joda-time:2.9.9'
}

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

if (properties['keystore'] == null || properties['keystore.password'] == null ||
    properties['keystore.key.alias'] == null || properties['keystore.key.password'] == null) {
    println("Cannot sign .apk: specify keystore, keystore.password, keystore.key.alias, and keystore.key.password in local.properties.")
}
else {
    android {
        signingConfigs {
            release {
                storeFile file(properties['keystore'])
                storePassword properties['keystore.password']
                keyAlias properties['keystore.key.alias']
                keyPassword properties['keystore.key.password']
            }
        }
        buildTypes {
            release {
                signingConfig signingConfigs.release
            }
        }
    }
}

if (properties['google-play'] != null) {
    apply plugin: 'net.named-data.playground.play'

    play {
        track = 'alpha'
        jsonFile = file(properties['google-play'])
    }
}
